利用whistle调试WebSocket和Socket请求

whistle v1.6.0 (Github地址:https://github.com/avwo/whistle) 开始支持WebSocket和一般Socket的抓包、构造请求、以及修改发送或接收的数据。

请求抓包

打开whistle的Network,选中左侧请求列表中的WebSocket(Socket)请求,点击右侧的 Response -> Frames

WebSocket抓包:

Socket(TCP)请求,需要通过Tunnel代理连接whistle,再通过whistle转发,未避免whistle把普通Socket请求当成https或websocket请求,需要代理请求头添加个字段 x-whistle-policy: tunnel,下面以Node为例说明如何通过whistle转发Socket(TCP)请求(其它语言同理:先发一个http请求给whistle代理把请求信息带给whistle,whistle请求目标服务器成功后把连接返回):

模拟后台Socket Server代码:

const net = require('net');

const server = net.createServer();
server.on('connection', (client) => {
  client.on('error', () => {});
  client.on('data', (data) => {
    client.write(`Response: ${data}`);
  })
});
server.listen(9999);

客户端代码:

const http = require('http');
const net = require('net');

// whistle监听端口,根据实际情况设定
const PROXY_PORT = 8899;
// whistle所在服务器IP
const PROXY_HOST = '127.0.0.1';
// 连接whistle代理
const connect = (options) => {
  options = {
    method: 'CONNECT',
    host: PROXY_HOST,
    port: PROXY_PORT,
    path: `${options.host}:${options.port}`,
    agent: false,
    headers: {
      'x-whistle-policy': 'tunnel', // 必填,否则无法查看抓包数据
    }
  };
  return new Promise((resolve, reject) => {
    const client = http.request(options);
    client.once('connect', (req, socket) => resolve(socket));
    client.once('error', reject);
    client.end();
  });
};

const init = async () => {
  const options = { host: '127.0.0.1', port: 9999 };
  const socket = await connect(options);
  let index = 0;
  const send = () => {
    ++index;
    socket.write(`${index}. This is a JSON Object: {"test": "index=${index}"}`);
  };
  socket.on('data', (data) => {
    setTimeout(send, 3000);
  });
  send();
};

init().catch(err => {
  throw err;
});

构造请求

在Network的右侧Composer可以构造各种请求,包括http、https、WebSocket、Socket请求,可以直接填写要请求的url、方法、请求头、请求内容等,也可以直接从左侧列表把对应的数据拖过来。

以WebSocket Demo网站为例(http://demos.kaazing.com/echo/),建立如下连接,并发送数据(用Composer构造的WebSocket在Frames下面会出现一个Composer选项,用于向Server发送数据,也可以通过直接上传文件发送):

GET /echo HTTP/1.1
WebSocket-Protocol: 
Sec-WebSocket-Protocol: 
Sec-WebSocket-Extensions: x-kaazing-idle-timeout,x-kaazing-ping-pong,x-kaazing-http-revalidate

1

后面通过Frames里面的Composer发送什么数据后台就返回什么:

一般Socket请求只需把请求方法改为 CONNECT,或者用这些协议的url conn://connect://socket://、、tunnel://

修改数据

从上面的插图可以发现,如果请求不是通过whistle的Composer发送的,WebSocket和Socket请求都无法添加或修改接收及发送数据(Composer建立的连接可以发送数据到服务端),要修改WebSocket或Socket的发送或接收数据,需要借助whistle的插件whistle.script,其原理是通过配置whistle规则把请求转发到whistle.script里面的WebSocket或Socket服务器,再通过whistle.script拦截或发送到指定后台。

安装whistle.script

npm i -g whistle.script
# 或
npm i -g whistle.script --registry=https://registry.npm.taobao.org

调试WebSocket请求,打开插件script的界面http://local.whistlejs.com/whistle.script/,新建名为handleWebSocket的script:

exports.handleWebSocket  = async (ws, connect) => {
      // 将请求继续转发到目标后台,如果不加则直接响应
    const res = await connect();
      // 获取客户端的请求数据
    ws.on('message', (data) => {
      // 在script的Console打印出客户端发送的数据
      console.log(`Client: ${data}`);
       // 可以修改后再发送到Server
       res.send(data);
    });
      res.on('message', (data) => {
        // 在script的Console打印出服务端发送的数据
        console.log(`Server: ${data}`);
         // 可以修改后再发送到Server
         ws.send(data);
    });
    // 接收通过whistle.script页面Console的dataSource.emit('toSocketClient', {name: 'toSocketClient'})的数据
    ws.dataSource.on('toSocketClient', (data) => {
      ws.send(data);
    });
   // 接收通过whistle.script页面Console的dataSource.emit('toSocketServer', {name: 'toSocketClient'})的数据
      ws.dataSource.on('toSocketServer', (data) => {
      res.send(data);
    });
};

在whistle上配置规则:

ws://demos.kaazing.com/echo script://handleWebSocket

打开http://demos.kaazing.com/echo/,点击 Connect 按钮:

调试Socket请求,同上操作在whistle.script插件上新建一个名为 handleSocket 的脚本:

exports.handleTunnel  = async (client, next) => {
      // 将请求继续转发到目标后台,如果不加则直接响应
     const res = await next();
      // 获取客户端的请求数据
    client.on('data', (data) => {
      // 在script的Console打印出客户端发送的数据
      console.log(`Client: ${data}`);
       // 修改后再发送到Server
       res.write(`Client>>>Server: ${data}+client`);
    });
      res.on('data', (data) => {
        // 在script的Console打印出服务端发送的数据
        console.log(`Server: ${data}`);
         // 修改后再发送到Server
         client.write(`Server>>>Client: ${data}`);
    });
    // 接收通过whistle.script页面Console的dataSource.emit('toSocketClient', {name: 'toSocketClient'})的数据
    client.dataSource.on('toSocketClient', (data) => {
      client.write(JSON.stringify(data));
    });
   // 接收通过whistle.script页面Console的dataSource.emit('toSocketServer', {name: 'toSocketClient'})的数据
      client.dataSource.on('toSocketServer', (data) => {
      res.write(JSON.stringify(data));
    });
};

在whistle上配置规则:

127.0.0.1:9999 script://handleSocket

启动文章刚开始的Socket连接的例子,打开whistle.script界面的Console,在里面分别执行下面两个语句:

dataSource.emit('toSocketClient', 'Mock Server');
dataSource.emit('toSocketServer', 'Mock Client');

whistle.script会把对应的事件名称及参数值传给后台 ctx.dataSource 的对应监听方法。

招聘信息

腾讯在线教育部前端团队急招大量优秀前端开发(Node、React、RN、Vue、weex等方面的人才,不管全栈还是只专注某个领域的都可以,了解职位信息点击这里),这边各方面(你懂的)在业界都是相当有竞争力,考虑大家年底换工作可能拿不到年终奖,老板说了入职后这边都会给相应的补偿,所以这点不需要太担心,有想换工作的或者追求更好发展平台把简历发我邮箱 avwu@qq.com,只要合适我们会立即安排面试。

相关文章

  1. whistle工具全程入门
  2. 利用whistle调试移动端页面
  3. Github地址

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏安智客

Android 8.0 中的安全增强功能

每个 Android 版本中都包含数十种用于保护用户的安全增强功能。以下是 Android 8.0 中提供的一些主要安全增强功能: 加密:在工作资料中增加了对...

18910
来自专栏重庆的技术分享区

详述前端安全问题及解决方案

CSRF攻击(cross site request forgery,跨站请求伪造)

4779
来自专栏deed博客

win2003服务器安全设置教程

1524
来自专栏张善友的专栏

IIS 7.0探索用于 Windows Vista 的 Web 服务器和更多内容

我经常听到 Microsoft 内部和外部的人将新的 IIS 7.0 Web 服务器称为 Microsoft 在过去几年中所进行的最重要的开发工作之一。考虑到 ...

1849
来自专栏北京马哥教育

5个你必须知道的Docker实用工具

原文:5 Docker Utilities You Should Know 作者:Shekhar Gulati 翻译:Vincent Docker社区已经创建了...

3269
来自专栏逸鹏说道

Linux包系列的知识(附:Ubuntu16.04升级到18.04的案例)

Linux基础:https://www.cnblogs.com/dunitian/p/4822808.html#linux

954
来自专栏北京马哥教育

使用 Nginx 提升网站访问速度

本文主要介绍如何在 Linux 系统上安装高性能的 HTTP 服务器 —— Nginx、并在不改变原有网站结构的条件下用 Nginx 来提升网站的访问速度。 N...

3468
来自专栏逸鹏说道

C#通过WMI的wind32 的API函数实现msinfo32的本地和远程计算机的系统摘要信息查看功能

最近做一个项目碰到要实现查看本地和远程计算机的摘要信息,采用命令行msinfo32可以很快查看到,如下图: ? 需要在用C#来实现类似信息查看。尤其远程计算机的...

3365
来自专栏开源优测

渗透测试 - kali Linux

渗透测试操作系统 - kali 什么是kali Kali Linux是基于Debian的Linux发行版, 设计用于数字取证操作系统。 由Offensive S...

3454
来自专栏小俊博客

VPS使用SolusVM开设OpenVZ的NAT机器全步骤教程

现在到处都是卖NAT机器的网站,俗称oneman,就是一个人可以搞定一切IDC业务(混IDC圈的都知道吧),对,没错,我相信大家手里VPS多的很,吃灰的也多,为...

1132

扫码关注云+社区