说明 - socat的简单使用

Posted by morouu on 2021-12-27
Estimated Reading Time 8 Minutes
Words 1.8k In Total
Viewed Times

说明 - socat的简单使用


- socat 简介 -

socat是一个多功能的网络工具,名字来由是” Socket CAT”,可以看作是netcat的N倍加强版,其原版本是基于Linux的,这里我们使用Windows版本的,因为是移植过来的,需要依赖的库也比较多,所以不是那么的方便,以后的使用可能更多的是基于Linux平台来进行的。

socat的主要特点就是在两个数据流之间建立通道;且支持众多协议和链接方式:ip, tcp, udp, ipv6, pipe,exec,system,open,proxy,openssl,socket等。


- socat 安装 -

- socat 安装 (Linux) -

  • 通过源码方式安装:

    1
    2
    3
    4
    5
    cd $HOME && mkdir -p socat/src && cd $HOME/socat/src
    wget http://www.dest-unreach.org/socat/download/socat-1.7.3.4.tar.gz
    tar zxf socat-1.7.3.4.tar.gz && cd socat-1.7.3.4 && $HOME/socat/src/socat-1.7.3.4/configure
    make
    make install

    若出现 fips 错误,则可以使用以下命令:

    1
    configure --disable-fips

    或者安装fips:

    1
    2
    3
    4
    5
    cd $HOME && mkdir -p fips/src && cd $HOME/fips/src
    wget https://www.openssl.org/source/openssl-fips-2.0.16.tar.gz
    tar zxf openssl-fips-2.0.16.tar.gz && cd openssl-fips-2.0.16 && $HOME/socat/src/openssl-fips-2.0.16/configure
    make
    make install
  • 通过包安装:

    1
    2
    yum update && yum install -y socat
    apt-get update && apt-get install -y socat

- socat 安装(windows) -

  • 通过github安装:

    1
    git clone https://github.com/StudioEtrange/socat-windows

- socat 基本工作原理 -

socat 的基本语法:

1
socat [option] <address1> <address2>

socat 实例的生命周期通常由四个阶段组成:

  • 初始化阶段:

    • socat 会先解析命令行选项并初始化日志。
  • 开启阶段:

    • socat 会先打开第一个地址,然后再打开第二个地址;这些步骤通常是阻塞的;因此,特别是对于负载的地址类型(如socks),会在下一步开始之前完成身份认证。
  • 传输阶段:

    • socat 会通过via select() 有选择的监视文件的读写流描述符,当数组在一端可用并且可以写入另一端时,socat将读取它,如果有需要,会对换行符进行转换,并将数据写入另一个流的写文件描述符,然后继续双向等待更多数据。(相当于这两个连接中谁有数据传过来就把数据传到另一个连接上,read/write互换)
  • 关闭阶段:

    • 当其中一个流有效的达到EOF时,该阶段就开始了。socat 将EOF的条件转移到另一个流,即尝试只关闭它的写流,给它一个终止的机会。在规定的时间内,socat 会继续向其他方向传输数据,但随后关闭所有剩余的信道并终止。

- socat 基本用法 -

  • 简单的读/写文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 读文件
    socat - `pwd`/a.txt
    socat /etc/issue -

    # 写文件
    echo "aaa" | socat - /tmp/aaaa # 不会有回显
    echo "bbb" | socat /tmp/bbbb - # 会有回显
    echo "ccc" | socat - open:/tmp/cccc,create # 不会有回显
    echo "ddd" | socat open:/tmp/dddd,create,append - # 会有回显,这个执行顺序是先显示/tmp/dddd文件的内容,然后再写入

    其中 ‘ - ‘ 相当于 STDIN + STDOUT,也就是读写流,由于socat会有选择的处理数据流,因此用socat进行简单的读/写文件,’ - ‘ 的顺序不重要。

  • 简单的执行命令:

    1
    2
    3
    4
    # 执行命令
    echo "ls" | socat - exec:bash,stderr
    echo "ls" | socat exec:bash,stderr -
    echo "ls" | socat - system:bash,stderr
  • 连接/监听TCP/UDP:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 连接TCP/UDP

    socat - tcp-connect:127.0.0.1:2333
    socat - udp-connect:127.0.0.1:2333

    # 监听TCP/UDP

    socat tcp-listen:2333 -
    socat tcp-listen:2333 -
  • 向TCP/UDP端口发送数据:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 向TCP发送数据

    echo "hello" | socat - tcp-connect:127.0.0.1:2333
    cat /etc/issue | socat - tcp-connect:127.0.0.1:2333
    socat /etc/issue tcp-connect:127.0.0.1:2333

    # 向UDP发送数据

    echo "hello" | socat - udp-connect:127.0.0.1:2333
    cat /etc/issue | socat - udp-connect:127.0.0.1:2333
    socat /etc/issue udp-connect:127.0.0.1:2333
  • 端口转发:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    # 简单的TCP/UDP端口转发

    socat tcp-listen:2333 tcp-connect:2334
    socat udp-listen:2333 udp-connect:2334

    # 支持并发的TCP/UDP端口转发

    socat tcp-listen:2333,fork tcp-connect:2334
    socat udp-listen:2333,fork udp-connect:2334

    # 将内容写入日志的并发端口转发

    socat -d -d -lf /tmp/log tcp-listen:2333,fork tcp-connect:2334
    socat -d -d -lf /tmp/log udp-listen:2333,fork udp-connect:2334

    # 将内容写入日志、并发、绑定地址的端口转发

    socat -d -d -lf /tmp/log tcp-listen:2333,fork,reuseaddr tcp-connect:2334
    socat -d -d -lf /tmp/log udp-listen:2333,fork,reuseaddr udp-connect:2334

    # 将内容写入日志、并发、绑定地址、指定IP的端口转发

    socat -d -d -lf /tmp/log tcp-listen:2333,fork,reuseaddr,bind=127.0.0.1 tcp-connect:2334
    socat -d -d -lf /tmp/log udp-listen:2333,fork,reuseaddr,bind=127.0.0.1 udp-connect:2334

    # 比如这个listen只允许127.0.0.1IP连接

    # 将内容写入日志、并发、绑定地址、指定IP、指定连接的IP段的端口转发

    socat -d -d -lf /tmp/log tcp-listen:2333,fork,reuseaddr,bind=127.0.0.1,range=127.0.0.1/24 tcp-connect:2334
    socat -d -d -lf /tmp/log udp-listen:2333,fork,reuseaddr,bind=127.0.0.1,range=127.0.0.1/24 udp-connect:2334

    # 比如这个listen只允许127.0.0.1IP连接,并且connect的内容只允许127.0.0.1 ~ 127.0.0.255段的IP

    # 内网穿透的端口转发

    # 外网服务器

    socat tcp-listen:2333 tcp-listen:80,fork

    # 本地主机

    socat tcp-connect:[外网IP]:2333 tcp-connect:127.0.0.1:80,fork(本地服务器)

    # 将内网rdp转发出去

    # 外网服务器

    socat tcp-listen:4447,reuseaddr,fork tcp-listen:3389

    # 本地主机

    socat tcp:[外网IP]:4447,reuseaddr,fork tcp:127.0.0.1:3389
  • 重定向:

    1
    2
    3
    4
    5
    6
    7
    8
    # 简单的重定向

    socat tcp-listen:80,reuseaddr,fork tcp:127.0.0.1:8080
    socat tcp-listen:7999,reuseaddr,fork tcp:127.0.0.1:3389

    # 将连接用户以特定用户去连接

    socat tcp-listen:2333,reuseaddr,fork,su=nobody tcp-connect:127.0.0.1:2334
  • 读写分流:

    1
    2
    3
    4
    5
    6
    7
    # 实现一个假的webServer

    socat open:/tmp/read.txt!!open:/tmp/write.txt,create,append tcp-listen:80,reuseaddr,fork

    # 每当客户端连接过来时,会fork出一个进程处理,然后先将read.txt文件的内容作为响应内容发回去,再把用户的请求内容记录在write.txt文件中。

    # 其中 !! 作为读/写流的分割,前边为读,后边为写。
  • 文件传输:

    1
    2
    3
    4
    5
    6
    # 实现简单的文件传输

    socat -u open:/etc/issue tcp-listen:3337,reuseaddr,fork
    socat -u tcp-connect:127.0.0.1:3337 open:/tmp/ok.txt,create

    # 其中 -u 意思为左边传右
  • 正向SHELL:

    1
    2
    3
    4
    5
    6
    7
    8
    # 服务器

    socat tcp-listen:3600,fork,reuseaddr exec:/bin/bash,pty,stderr
    socat tcp-listen:3600,fork,reuseaddr system:bash,pty,stderr

    # 客户端

    socat tcp-connect:127.0.0.1:3600
  • 反向SHELL:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # 服务器

    socat tcp-connect:127.0.0.1:3601 exec:/bin/bash,pty,stderr

    # 客户端

    socat - tcp-listen:3601

    # 可交互的反弹shell

    # 服务器

    socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp-connect:127.0.0.1:3601

    # 客户端

    socat file:`tty`,raw,echo=0 tcp-listen:3601
  • 通过openssl加密传输:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    # 1. 生成服务器证书

    openssl genrsa -out server.key 2048
    openssl req -new -key server.key -x509 -days 365 -out server.crt

    # 这里把 Common Name 设为localhost方便测试

    cat server.key server.crt > server.pem

    # 2. 生成客户端证书

    openssl genrsa -out client.key 2048
    openssl req -new -key client.key -x509 -days 365 -out client.crt

    # 这里随便设置

    cat client.key client.crt > client.pem

    # 服务器

    socat openssl-listen:4433,reuseaddr,cert=server.pem,cafile=client.crt echo

    #客户端
    socat - openssl-connect:localhost:4433,cert=client.pem,cafile=server.crt

如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。也欢迎您共享此博客,以便更多人可以参与。如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。谢谢 !