socat-fu-lesson

From: https://www.pentestpartners.com/blog/socat-fu-lesson/


Posted on Friday, September 19th, 2014 by Pedro Venda.

I’m going to show you how socat is used to solve real-life penetration testing problems. Socat is a fantastically versatile Swiss army knife for connecting all sorts of sockets, be they TCP, UDP, IPv4, IPv6, SSL-wrapped, unix sockets, raw sockets, etc.

There are six examples here, varying in complexity from a simple TCP connection to a remote service, through to transparent hijacking of traffic into a socat endpoint.


Basic:

  • Case 1: Tunnel a connection from a local TCP port to a remote service
  • Case 2: Tunnel a plain text connection to an SSL endpoint (and vice-versa)

Moderate:

  • Case 3: Man in the middle an SSL connection that you can control
  • Case 4: Modify HTTP traffic in transit to disable gzip/deflage encodings

Advanced:

  • Case 5: Transparent hijacking of traffic into a socat endpoint

Bonus:

  • Case 6: Help! There is no netcat or socat!

:Start

Case 1: Tunnel a connection from a local TCP port to a remote service

Difficulty: Easy
Usefulness: Low to moderate

$ socat -v tcp4-listen:8000,reuseaddr,fork tcp4:6.6.6.6:80

Connections to localhost:8000 will end up at port 80 of remote host 6.6.6.6. Socat forks a new process for every connection so multiple connections can be made to the local port without requiring restarting socat.

GOTO :End


Case 2: Tunnel a plain text connection to an SSL endpoint (and vice-versa)

Difficulty: Easy
Usefulness: High

$ socat -v tcp4-listen:9000,reuseaddr,fork ssl:6.6.6.6:443,verify=0

Plain text connections to localhost on port 9000 will terminate at the remote host 6.6.6.6 in an SSL tunnel. This is particularly useful when certain tools do not deal with SSL correctly or when certificates get in the way. Socat can be used to establish the SSL connection while presenting a plain text endpoint, thus masking or hiding the encryption layer. This model can be extended to enable the use of a client side certificate, which further helps to mask this layer of complexity (which some tools might not support).

$ socat -v tcp4-listen:9000,reuseaddr,fork ssl:6.6.6.6:443,verify=0,cert=./provisional_prov.pem

The opposite is also possible (with or without client certificate authentication), with the added requirement that server-side certificates must exist for socat to be able to host SSL/TLS connections.

$ socat -v openssl-listen:7000,cert=cert.pem,verify=0,reuseaddr,fork tcp4:6.6.6.6:6000

In this case an SSL/TLS connection to localhost on port 7000 is piped to the remote host 6.6.6.6 on port 6000.

GOTO :End


Case 3: Man in the middle an SSL connection that you can control Difficulty: Moderate Usefulness: High (specific)

All the above cases can be combined in weird and complicated ways to confuse your colleagues and clients implement useful but complex network tunnels. Socat makes it very easy to terminate an SSL/TLS connection, pipe the data in plain text into another socat instance which forwards it through an SSL/TLS tunnel to the end service. The end result is visibility and ability to modify traffic in plain text which would otherwise be going through the SSL tunnel.

Traffic flows roughly as per the diagram below:

“Application” ==SSL==> socat #1 —plain—> socat #2 ==SSL==> Remote service

The commands below should be executed in reverse order in separate shells:

#1: $ socat -v openssl-listen:6000,cert=cert.pem,verify=0,reuseaddr,fork tcp4:localhost:6500
#2: $ socat -v tcp4-listen:6500,reuseaddr,fork ssl:6.6.6.6:443,verify=0

NOTE: socat won’t connect the second socket until a connection is received on the first, therefore the order of the above commands is normally irrelevant. But for correctness, the second command should be started in first place.

GOTO :End


Case 4: Modify HTTP traffic in transit to disable gzip/deflage encodings

Difficulty: Moderate
Usefulness: Medium (specific)

Netsed is another very useful tool to play with plaintext network traffic. This is a very simple example where the keywords ‘gzip’ and ‘deflate’ are removed from HTTP headers whilst maintaining the request length. The commands below should be executed in reverse order in separate shells:

“Application” ==SSL==> socat #1 —plain—> netsed —plain—> socat #2 ==SSL==> Remote service

#1: $ socat -v openssl-listen:6000,cert=cert.pem,verify=0,reuseaddr,fork tcp4:localhost:6500
#2: $ netsed tcp 6500 127.0.0.1 6750 's/gzip/ ' 's/deflate/ '
#3: $ socat -v tcp4-listen:6750,reuseaddr,fork ssl:6.6.6.6:443,verify=0

The application connects to socat #1 on port 6000 over SSL. socat #1 pipes the traffic in plain text through netsed (#2) which modifies content on the fly and forwards it to a second instance of socat #2. Socat #2 in turn forwards the modified traffic via an SSL connection to the remote server.

Modifying the workstation’s ‘hosts’ file is a helpful tweak to help forward traffic from applications that use hard coded host names rather than IP addresses.

GOTO :End


Case 5: Transparent hijacking of traffic into a socat endpoint

Difficulty: Advanced
Usefulness: Medium (specific)

This is where it all comes together. Supposed you want to modify traffic coming from an application running on a Windows workstation that connects to a hard coded IP address over SSL on a hard coded port. [This precludes dealing with certificate validity which can in most cases be taken care of (technically all cases, but some are harder than others)].

A possible solution is to add a static route into a Linux virtual machine connected to the Internet via a bridged interface, setup iptables to hijack the traffic and forward to a local port (remember that traffic is aimed at a remote address, so Linux would attempt to route it) and get the socat array of processes piping the traffic through the assembly line of hacking through towards the remote host as intended by the application.

A couple of definitions:
Remote service is 6.6.6.6 on port 9999;
VM address: 192.168.81.131 (eth0)
VM briged gateway address: 192.168.1.254 (eth1)

Step 1: redirect traffic to VM (Windows workstation)

$ route -p add 6.6.6.6 mask 255.255.255.255 192.168.81.131 metric 1 if 20

Traffic going to IP 6.6.6.6/32 should be delivered to host 192.168.81.131 (the Linux VM) on interface 0x20 (check with route print which interface index connects where) with full priority (metric 1).

At this point, the Linux VM will receive traffic coming from the test app towards the remote server on port 9999, but the traffic is either routed/forwarded or dropped.

Step 2: hijack application traffic (Linux VM)

# echo -n 1 > /proc/sys/net/ipv4/ip_forward # enable forwarding
# ip route del default ... # normally the NATted interface
# ip route add default via 192.168.1.254 # route traffic out via a bridged interface rather than returning on a NATted interface

NOTE: The Linux VM should connect to the Internet via a bridged interface as opposed to connecting back via a NATted connection to the host Workstation. This is because once the traffic returns to the workstation, its target returns to the VM because of the static route created to forward the traffic, as originally intended.

# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE # NAT/masquerade outbound traffic # iptables -t nat -A PREROUTING -p tcp --dport 9999 -d 6.6.6.6 -j

REDIRECT –to 6000 # redirect traffic aimed at 6.6.6.6 port 9999 to local port 6000

:Step3
GOTO :Case4;


Case 6:Help! There is no socat or netcat!

If you happen to be using a system with a bash shell available, then TCP connections can be done by interacting with a pseudo-filesystem provided by the shell itself in the shape of /dev/tcp// which uses the connect() system call. This facility makes it very easy to connect to a remote host and transfer data onto it. Listening on a port, however, is not something that bash facilitates (because there is no provided equivalent pseudo-filesystem that uses the bind() system call).

$ exec 8<>/dev/tcp/6.6.6.6/80

Open a file descriptor and point it at the virtual file /dev/tcp/6.6.6.6/80, which is the same as connecting the file descriptor to the remote tcp port of host 6.6.6.6 (host names can be used too) on port 80. This is a read-write file descriptor as shown below.

$ echo -e "GET / HTTP/1.0\r\n\r\n" >&8

Write a basic HTTP request onto the file descriptor.

$ cat <&8

Finally read the response into standard output. Job done!

GOTO :End;

:End

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值