Sekiro Environment Basic Setup for WSS

1. Server Deployment

Project link: https://github.com/yint-tech/sekiro-open

Official documentation link: https://sekiro.iinti.cn/sekiro-doc/01_manual/4.server_install.html

The environment used is Ubuntu 20.

Installation steps:

  1. Install Docker, you can refer to this article here.
  2. Install docker-compose: sudo pip install docker-compose.
  3. Install Sekiro:

After starting Docker, execute the following command:

curl https://oss.iinti.cn/sekiro/quickstart.sh | bash
  1. Open the URL http://(server's IP):5612, and register an account (the first registered account is the super administrator).

img.png

2. Client Connection to Server

You can refer to the official documentation here.

If your injected website has same-origin detection interception for wss, even if you can create a wss connection, it may be blocked due to same-origin issues.
Assuming the website being accessed is: https://xxx.abc.com
Use wss to connect to Sekiro: wss://sekiro.iinti.cn/business/register?group=ws-group&clientId=1221
If www.abc.com has a same-origin policy interception, it may result in an error: 'refused to connect to 'wss://sekiro.iinti.cn/business/register?group=ws-group&clientId=1221' because of it violates the following Content Security Policy directive: xxxxxx

Pre-installation of CA Certificate

Click here for the PEM format or the CRT format to download the certificate and follow the system guidance to install the root certificate.

Method 1: Using a Proxy to Solve CSP

Sekiro’s port service implements an HTTP/HTTPS proxy. You can directly set the Sekiro port as the proxy for your browser.

If your injected website has same-origin detection interception for wss, you can set the browser’s proxy to the Sekio server. At this point, because all traffic can pass through the Sekiro server and Sekiro has a CA root certificate to decrypt and forge traffic, the wss connection can be constructed directly using the domain name corresponding to the main webpage. Sekiro can perceive that this connection needs to be forwarded to the Sekiro server, and will automatically handle it internally.

This method can perfectly solve the wss same-origin interception problem.

Please note that when accessing Sekiro through a proxy, Sekiro will inevitably enable SSL decryption. At this point, it is necessary to install Sekiro’s CA certificate (as mentioned above), otherwise, HTTPS web pages will be blocked because the certificate is not trusted.

Method 2: Constructing Subdomains to Solve CSP

If the entire Sekiro server is set as a proxy server, all traffic will be directed to the Sekiro server. When considering multi-browser cluster control, multiple IP aggregations may bring risk control issues, and using the Sekiro server as the exit IP may also bring risk control issues. In this case, you can use a PAC script to control the WebSocket connection to the Sekiro server separately, while the rest of the traffic proceeds normally.

  1. Download the proxy plugin: https://github.com/FelisCatus/SwitchyOmega.
  2. Configure the PAC script.
function FindProxyForURL(url, host) {
    if (shExpMatch(url,"wss://*")) {
        // 只要是wss协议,则代理到sekiro.iinti.cn:5612
        // 这里实现比较粗暴,具体规则可根据网站实际调整
        return "PROXY sekiro.iinti.cn:5612";
    }
return "DIRECT";
}
  1. To create a WebSocket connection that mirrors the target website’s domain, you can utilize the provided JavaScript code:
var client = new SekiroClient("wss://xxx.abc.com/business/register?group=test-ws&clientId=" + Math.random());
client.registerAction("testAction", function (request, resolve, reject) {
    resolve("ok");
});
  1. For addressing CSP issues by constructing subdomains, the following steps can be followed:

    1. Assuming the Sekiro server is deployed at 47.93.16.121:443.
    2. Modify the hosts file to map the domain sekrio.xxx.abc.com to 47.93.16.121, thereby simulating the creation of a domain and binding it to the Sekiro server as a subdomain of the target website.
    3. Install the CA certificate to ensure that the system’s root certificate is installed and the Sekirio certificate is trusted.
    4. Utilize the constructed subdomain’s wss connection: wss://sekiro.xxx.abc.com/business/register?group=ws-group&clientId=1221 to establish the connection.

    It’s important to note that the CSP rules need to support wss connections, specifically connect-src wss:. Without this support, only a proxy-based approach would be feasible, as CSP rules typically restrict WebSocket loading from HTTP pages.

Regarding wss injection, you can replicate the official code. If you have any specific questions or need further assistance, feel free to ask!

function SekiroClient(e){if(this.wsURL=e,this.handlers={},this.socket={},!e)throw new Error("wsURL can not be empty!!");this.webSocketFactory=this.resolveWebSocketFactory(),this.connect()}SekiroClient.prototype.resolveWebSocketFactory=function(){if("object"==typeof window){var e=window.WebSocket?window.WebSocket:window.MozWebSocket;return function(o){function t(o){this.mSocket=new e(o)}return t.prototype.close=function(){this.mSocket.close()},t.prototype.onmessage=function(e){this.mSocket.onmessage=e},t.prototype.onopen=function(e){this.mSocket.onopen=e},t.prototype.onclose=function(e){this.mSocket.onclose=e},t.prototype.send=function(e){this.mSocket.send(e)},new t(o)}}if("object"==typeof weex)try{console.log("test webSocket for weex");var o=weex.requireModule("webSocket");return console.log("find webSocket for weex:"+o),function(e){try{o.close()}catch(t){}return o.WebSocket(e,""),o}}catch(t){console.log(t)}if("object"==typeof WebSocket)return function(o){return new e(o)};throw new Error("the js environment do not support websocket")},SekiroClient.prototype.connect=function(){console.log("sekiro: begin of connect to wsURL: "+this.wsURL);var e=this;try{this.socket=this.webSocketFactory(this.wsURL)}catch(o){console.log("sekiro: create connection failed,reconnect after 2s"),setTimeout(function(){e.connect()},2e3)}this.socket.onmessage(function(o){e.handleSekiroRequest(o.data)}),this.socket.onopen(function(e){console.log("sekiro: open a sekiro client connection")}),this.socket.onclose(function(o){console.log("sekiro: disconnected ,reconnection after 2s"),setTimeout(function(){e.connect()},2e3)})},SekiroClient.prototype.handleSekiroRequest=function(e){console.log("receive sekiro request: "+e);var o=JSON.parse(e),t=o.__sekiro_seq__;if(!o.action)return void this.sendFailed(t,"need request param {action}");var n=o.action;if(!this.handlers[n])return void this.sendFailed(t,"no action handler: "+n+" defined");var s=this.handlers[n],i=this;try{s(o,function(e){try{i.sendSuccess(t,e)}catch(o){i.sendFailed(t,"e:"+o)}},function(e){i.sendFailed(t,e)})}catch(r){console.log("error: "+r),i.sendFailed(t,":"+r)}},SekiroClient.prototype.sendSuccess=function(e,o){var t;if("string"==typeof o)try{t=JSON.parse(o)}catch(n){t={},t.data=o}else"object"==typeof o?t=o:(t={},t.data=o);(Array.isArray(t)||"string"==typeof t)&&(t={data:t,code:0}),t.code?t.code=0:t.status?t.status=0:t.status=0,t.__sekiro_seq__=e;var s=JSON.stringify(t);console.log("response :"+s),this.socket.send(s)},SekiroClient.prototype.sendFailed=function(e,o){"string"!=typeof o&&(o=JSON.stringify(o));var t={};t.message=o,t.status=-1,t.__sekiro_seq__=e;var n=JSON.stringify(t);console.log("sekiro: response :"+n),this.socket.send(n)},SekiroClient.prototype.registerAction=function(e,o){if("string"!=typeof e)throw new Error("an action must be string");if("function"!=typeof o)throw new Error("a handler must be function");return console.log("sekiro: register action: "+e),this.handlers[e]=o,this};

var client = new SekiroClient("wss://www.linkedin.cn/business/register?group=ws-group&clientId=" + Math.random());
client.registerAction("testAction", function (request, resolve, reject) {
    c = undefined;
    resolve(window.ja("d_incareer2_profile_homepage", c));
});

The browser calls the interface successfully.

img_1.png