内容纲要

Socat是一个比较实用的命令行工具 , 它建立两个双向字节流并在它们之间传递数据 .

Socat实例的生命周期通常分为四个阶段

  1. Init阶段 : Socat解析命令行的选项参数并初始化记录日志

  2. Open阶段 : Socat先打开第一个地址 , 完毕后打开第二个地址 , 这两个步骤是阻塞执行的 . 特别是像 socket 这样的复杂地址类型 , 连接请求或者身份验证的操作必须要在下一个步骤之前完成 . 如果其中一个地址打开失败 , 那么socat将直接退出

  3. Transfer阶段 : Socat通过selct()监视数据流的读写文件描述符 , 当数据在一侧可读且可以写入另一侧时 , Socat读取它们 . 在需要时执行换行符转换 , 将读取的数据写入到另一侧的写文件描述符中 , 然后继续等待双向的数据

  4. Closing阶段 : 当从一个数据流中读取EOF( End Of File )时 , Socat将EOF条件写入到另一个数据流中 , 并尝试关闭写入流 . 待转发完剩下的数据流后 , 关闭剩下的一个数据并终止程序

这些内容其实在man手册里已经详细的说明了 , 这里仅是总结一下


Socat的参数太多了 , 不可能每个都进行总结 , 这里进说下常用的几个参数

socat [options] <addressA> <addressB>

前面说过 Socat 就是在两个地址之间建立管道 , 发送和接收数据 , 这里的<address>可以看作是双向字节流 , 也可以看成是文件描述符

这里<address>必须两个都要指定 , 否则会报错 ! 可以用 - 作为缺省地址

因为 <address>,[options] 的灵活多变 , 所以 Socat 可以用于各种的环境 , 这里从最简单的说起 , 由浅入深 .


Socat 作为 Cat 使用

  1. 读取输入流

    png

  2. 读取单个文件内容

    png

    需要注意的是 : 在读取内容时 , <address>参数必须使用 绝对路径 或者 是以./开头的相对路径 , 不能直接使用文件名!

  3. 写入文件内容

    png

    写文件时需要分清 写入追加 . socat addressA addressB 是把从 AddressA 中读取的内容追加到 AddressB


Socat 作为 Netcat 使用

  1. 监听端口并且传输数据

    1. NC实现

      png

    2. Socat实现

      png

  2. 正向Shell( 客户端连接服务器 , 获取服务器的Shell )

    1. NC实现

      png

      服务器将 /bin/bash 转发到2333端口上 , 当客户端连接2333端口 , 即可获得服务器的/bin/bash

    2. Socat实现

      png

  3. 反向Shell( 服务器连接客户端 , 获得客户端的Shell )

    1. NC实现

      png

    2. Socat实现

      png


代理与转发

png

将本机的4321端口收到的数据流转发到 192.168.56.102的1234端口上

fork : 设定多链接模式( 或者说是并发链接模式 ) , 当一个链接被建立后 , 自动复制一个同样的端口再进行监听


Socat创建 TLS/SSL 连接

为什么选择使用 Socat 而不是使用 Netcat ? 很大一部分原因是 Socat 支持 TLS/SSL 连接 !

网上对于Socat创建SSL连接基本都是一笔带过 , 我在学习中也踩了不少坑 , 这里把这些坑记录下来

  1. 首先在服务器生成私钥 , 这里命名为server.key

    png

     .key 文件一般是指私钥文件
    
  2. 生成一个自签名证书 , 会让你输入一系列信息

    png

    这里要填写一堆信息 , 相关信息如下所示

    png

     Common Name , 这个值不能不填且需要记住 , 后面会用到
    
    .CSR : Certificate Signing Requests 的缩写 , 即证书签名请求 . 在生成证书时需要把它提交给权威的证书颁发机构
    
  3. 将该CSR文件发送给CA注册一下 , 生成一个CA证书

    当然发给真正的CA是要钱的 , 咱只是做个实验 , 所以就把自己当做一个CA , 自己给自己注册一下( 也就是所谓 " 自签名证书 " )

    png

     CRT : Certificate的缩写 , 也就是证书啦
    
     X509是一种证书格式 , 对于X.509证书来说 , 认证者总是CA或者由CA指定的人 , 一份X.509证书是一些标准字段的集合 , 这些字段包含有关用户或者设备及其相应公钥的信息
    
  4. 生成PEM文件

    png

     PEM : PEM文件包含证书和私钥 , 这取决于您的证书/密钥的格式 . 
    
     上面提到生成了X.509格式的证书 , 根据该文件的内容编码格式 , 可以分为下面两种
    
     1. PEM , 以文本格式打开 , 可读 , 内容用Base64编码
    
     2. DER , 以二进制格式打开 , 不可读 
    
     Apache 和 Unix 服务器偏向使用PEM的编码格式 ~ 所以生成PEM文件
    
  5. 把上面四个步骤在客户端上再来一遍 , 全部命名为client.* , 注意在创建client.csr时 , 不能忽视Common Name

    png

  6. 客户端和服务器交换证书文件

    这里通过scp命令即可完成 , 将*.crt文件分别交换

    png

  7. 修改/etc/hosts文件

    之后我们要通过之前设置的Common Name建立TLS/SSL连接 , 但是机器是不知道这个Common Name是指向谁的 , 所以需要在/etc/hosts文件中指定

    png

现在准备工作都做完了 , 我们可以建立 TLS/SSL 通信了 . 为了便于实验 , 这里选择通过客户端发起一个正向Shell~

  • 现在服务器开启监听端口9999 , 并且向连接该端口的设备发送一个交互式的Shell

    png

  • 客户端发起TLS/SSL连接 , 注意连接目标为你之前指定的Common Name , 也就是你在/etc/hosts文件中指定的域名

    png

可以看到客户端成功获得了服务器的Shell , 正向连接搭建成功 !

     cert : 参数告诉 Socat 包含证书和私钥的文件( 也就是PEM文件 )

     cafile 参数指向客户端的证书文件( 也就是CRT文件 )

     如果客户端能提供相关联的私钥,我们则认为该连接是可靠的。

那么我怎么知道数据有没有被加密传输呢? 可以通过 WireShark 抓包来看一下~

  • 选择正确的端口 , 这里注意选择虚拟网卡~本机的环境是VirtualBox , 所以选择vboxnet0

    png

  • 在filter中选择仅监听SSL数据流 , 然后在客户端的Shell中发送数据~

    png

可以看到数据流走的是TLSv1.2协议 , 数据流成功被加密 !


总结

创建TLS/SSL连接是Socat的一大核心功能 , 也是越来越多人使用 Socat 而不是 Netcat 的原因 .

Linux中一切皆文件 , 一切能够在文件层访问的内容都可以称为 Socat 的数据流来源 , 这使得 Socat 的 <address> 可以任意发挥 , 功能非常强大!

最后修改日期:2019年9月17日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。