Skip to content

Instantly share code, notes, and snippets.

@SomajitDey
Created May 14, 2021 07:53
Show Gist options
  • Select an option

  • Save SomajitDey/b8d3f5e0786e09b5079d3accde107d4c to your computer and use it in GitHub Desktop.

Select an option

Save SomajitDey/b8d3f5e0786e09b5079d3accde107d4c to your computer and use it in GitHub Desktop.
1
2 // Examples for using socat (and filan)
3
4
5 //"$" means normal user, "#" requires privileges, "//" starts a comment
6
7 ///////////////////////////////////////////////////////////////////////////////
8 // similar to netcat
9
10 // connect to 10.1.1.1 on port 80 and relay to and from stdio
11 $ socat - TCP:10.1.1.1:80 # similar to "netcat 10.1.1.1 80"
12
13 // listen on port 25, wait for an incoming connection, use CR+NL on this
14 // connection, relay data to and from stdio;
15 // then emulate a mailserver by hand :-)
16 # socat - TCP-LISTEN:25,crlf
17
18 // listen on port 25, wait for an incoming connection, use CR+NL on this
19 // connection, relay data to and from stdio, but have line editing and history;
20 // then emulate a mailserver by hand :-)
21 # socat readline TCP-LISTEN:25,crlf
22
23 // provide a transient history enabled front end to stupid line based
24 // interactive programs
25 $ socat readline exec:"nslookup",pty,ctty,setsid,echo=0
26 // same works for ftp (but password is not hidden)
27
28 // you may also use a file based history list
29 $ socat readline,history=.nslookup_hist exec:"nslookup",pty,ctty,setsid,echo=0
30 // using ~ as abbreviation for $HOME does not work!
31
32 // poor mans 'telnetd' replacement
33 # socat tcp-l:2023,reuseaddr,fork exec:/bin/login,pty,setsid,setpgid,stderr,ctty
34 // and here an appropriate client:
35 $ socat -,raw,echo=0 tcp:172.16.181.130:2023
36 // use ssl with client and server certificate for improved security;
37 // replace /bin/login by /bin/bash when using SSL client authentication, can be
38 // run without root then
39
40 // this is a cool trick, proposed by Christophe Lohr, to dump communications to
41 // two files; it would also work for other manipulations (recode, compress...)
42 // and it might also work with netcat ;-)
43 $ socat TCP-LISTEN:5555 SYSTEM:'tee l2r | socat - "TCP:remote:5555" | tee r2l'
44
45 ///////////////////////////////////////////////////////////////////////////////
46 // emergence solution because usleep(1) is not always available
47 // this will "sleep" for 0.1s
48 $ socat -T 0.1 pipe pipe
49
50 ///////////////////////////////////////////////////////////////////////////////
51 // a very primitive HTTP/1.0 echo server (problems: sends reply headers before
52 // request; hangs if client does not shutdown - HTTP keep-alive)
53 // wait for a connection on port 8000; do not wait for request, but immediately
54 // start a shell that sends reply headers and an empty line; then echo all
55 // incoming data back to client
56 $ socat TCP-LISTEN:8000,crlf SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo; cat"
57
58 // a less primitive HTTP echo server that sends back not only the reqest but
59 // also server and client address and port. Might have portability issues with
60 // echo
61 ./socat -T 1 -d -d tcp-l:10081,reuseaddr,fork,crlf system:"echo -e \"\\\"HTTP/1.0 200 OK\\\nDocumentType: text/html\\\n\\\n<html>date: \$\(date\)<br>server:\$SOCAT_SOCKADDR:\$SOCAT_SOCKPORT<br>client: \$SOCAT_PEERADDR:\$SOCAT_PEERPORT\\\n<pre>\\\"\"; cat; echo -e \"\\\"\\\n</pre></html>\\\"\""
62
63 ///////////////////////////////////////////////////////////////////////////////
64 // for communicating with an attached modem, I had reasonable results with
65 // following command line. Required privileges depend on device mode.
66 // after leaving socat, type "sane".
67 // replace /dev/ttyS0 by the correct serial line or with /dev/modem
68 $ socat readline /dev/ttyS0,raw,echo=0,crlf
69 // or
70 $ socat readline /dev/ttyS0,raw,echo=0,crlf,nonblock
71 // then enter "at$"
72
73 ///////////////////////////////////////////////////////////////////////////////
74 // relay TCP port 80 from everywhere (internet, intranet, dmz) through your
75 // firewall to your DMZ webserver (like plug-gw)
76 // listen on port 80; whenever a connection is made, fork a new process (parent
77 // process keeps accepting connections), su to nobody, and connect to
78 // www.dmz.mydomain.org on port 80.
79 // attention: this is a substitute for a reverse proxy without providing
80 // application level security.
81 # socat TCP-LISTEN:80,reuseaddr,fork,su=nobody TCP:www.dmz.mydomain.org:80
82 // Note: parent process keeps running as root, su after forking
83
84 ///////////////////////////////////////////////////////////////////////////////
85 // relay mail from your DMZ server through your firewall.
86 // accept connections only on dmz interface and allow connections only from
87 // smtp.dmz.mydomain.org.
88 // the advantages over plug-gw and other relays are:
89 // * you can bind to an IP address (even an alias), therefore enhance security
90 // * in your OS you can create several IP aliases and bind another socat daemon
91 // to each, making several application servers addressable
92 // * lots of options, like switching user, chroot, IP performance tuning
93 // * no need for inetd
94 # socat -lm -d -d TCP-LISTEN:25,bind=fw.dmz.mydomain.org,fork,su=nobody,range=smtp.dmz.mydomain.org/32 TCP:smtp.intra.mydomain.org:25
95
96 ///////////////////////////////////////////////////////////////////////////////
97 // convert line terminator in ascii streams, stdin to stdout
98 // use unidirectional mode, convert nl to crnl
99 $ socat -u - -,crlf
100 // or cr to nl
101 $ socat -u -,cr -
102
103 // save piped data similar to 'tee':
104 // copies stdin to stdout, but writes everything to the file too
105 $ socat -,echo=0 open:/tmp/myfile,create,trunc,ignoreeof!!/tmp/myfile
106
107 ///////////////////////////////////////////////////////////////////////////////
108 // intrusion testing
109
110 // found an XWindow Server behind IP filters with FTP data hole? (you are
111 // lucky!)
112 // prepare your host:
113 # rm -f /tmp/.X11-unix/X1
114 // relay a pseudo display :1 on your machine to victim:0
115 # socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork TCP:host.victim.org:6000,sp=20 &
116 // and try to take a screendump (must be very lucky - when server has not even
117 // host based authentication!)
118 # xwd -root -display :1 -silent >victim.xwd
119
120 // you sit behind a socks firewall that has IP filters but lazily allows socks
121 // connections to loopback and has only host based X11 security.
122 // like above, but from your inside client:
123 # socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork SOCKS4:firewall:loopback:6000
124 // or for the HTTP proxy:
125 # socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork PROXY:firewall:loopback:6000
126
127 ///////////////////////////////////////////////////////////////////////////////
128 // forms of stdin with stdout, all equivalent
129 $ socat echo -
130 $ socat echo STDIO
131 $ socat echo STDIN!!STDOUT
132 $ socat echo STDIO!!STDIO
133 $ socat echo -!!-
134 $ socat echo FD:0!!FD:1
135 $ socat echo 0!!1
136 $ socat echo /dev/stdin!!/dev/stdout // if your OS provides these
137
138 ///////////////////////////////////////////////////////////////////////////////
139 // some echo address examples
140 $ socat - PIPE
141 $ socat - PIPE:/tmp/pipi // other version of echo
142 $ socat - PIPE:/tmp/pipi,nonblock!!/tmp/pipi // other version of echo
143 $ socat - EXEC:/bin/cat // another echo
144 $ socat - SYSTEM:/bin/cat // another echo
145 $ socat - TCP:loopback:7 // if inetd echo/TCP service activated
146 $ socat - UDP:loopback:7 // if inetd echo/UDP service activated
147 $ socat - /tmp/hugo,trunc,ignoreeof!!/tmp/hugo // with delay
148 $ socat - UDP:loopback:2000,bind=:2000 // self "connection"
149 $ socat - TCP:loopback:2000,bind=:2000 // Linux bug?
150 # socat - IP:loopback:222 // raw protocol, self "connected" (attention,
151 // Linux might drop packets with less than 8 bytes payload)
152
153 ///////////////////////////////////////////////////////////////////////////////
154 // unidirectional data transfer
155 $ socat -u - -
156 // like "tail -f", but start with showing all file contents
157 $ socat -u FILE:/var/log/syslog.debug,ignoreeof -
158 // like "tail -f", but do not show existing file contents
159 $ socat -u FILE:/var/log/syslog.debug,ignoreeof,seek-end -
160 // write to new file, create with given permission and group (must be member) - race condition with group!!!
161 $ socat -u - CREATE:/tmp/outfile1,group=floppy,perm=0640
162 //
163 // for an existing file /tmp/outfile1
164 # socat -u - FILE:/tmp/outfile1,group=floppy,perm=0700,user=4321
165
166
167 ///////////////////////////////////////////////////////////////////////////////
168 // file handling
169 $ socat - FILE:/tmp/outfile1,ignoreeof!!FILE:/tmp/outfile1,append // prints outfile1, then echoes input and protocols into file (appends to old data)
170
171 ///////////////////////////////////////////////////////////////////////////////
172 // unix socket handling
173
174 // create a listening unix socket
175 $ rm -f /tmp/mysocket; socat UNIX-LISTEN:/tmp/mysocket -
176 // from another terminal, connect to this socket
177 $ socat UNIX:/tmp/mysocket -
178 // then transfer data bidirectionally
179
180
181 ///////////////////////////////////////////////////////////////////////////////
182 // transport examples
183
184 // socks relay (externally socksify applications);
185 // your ssh client and OS are not socksified, but you want to pass a socks
186 // server with ssh:
187 $ socat TCP-LISTEN:10022,fork SOCKS4:socks.mydomain.org:ssh-serv:22
188 $ ssh -p 10022 loopback
189 // or better define a ProxyCommand in ~/.ssh/config:
190 ProxyCommand socat - SOCKS:socks.mydomain.org:%h:%p
191 // and with proxy:
192 ProxyCommand socat - PROXY:proxy.mydomain.org:%h:%p,proxyport=8000
193
194 ///////////////////////////////////////////////////////////////////////////////
195 // application examples
196
197 // run sendmail daemon with your favorite network options
198 # socat TCP-LISTEN:25,fork,ip-ttl=4,ip-tos=7,tcp-maxseg=576 EXEC:"/usr/sbin/sendmail -bs",nofork
199
200 // local mail delivery over UNIX socket - no SUID program required
201 # socat UNIX-LISTEN:/tmp/postoffice,fork,perm-early=0666 EXEC:"/usr/sbin/sendmail -bs"
202 $ socat - /tmp/postoffice
203
204 ///////////////////////////////////////////////////////////////////////////////
205 // uses of filan
206 // see what your operating system opens for you
207 $ filan
208 // or if that was too detailled
209 $ filan -s
210 // see what file descriptors are passed via exec function
211 $ socat - EXEC:filan,nofork
212 $ socat - EXEC:filan
213 $ socat - EXEC:filan,pipes,stderr
214 $ socat - EXEC:filan,pipes
215 $ socat - EXEC:filan,pty
216 // see what's done by your shell and with option "pipes"
217 $ socat - SYSTEM:filan,pipes
218 // see if gdb gives you an equivalent environment or opens some files for your program
219 $ gdb ./filan
220 (gdb) r
221 (gdb) r -s
222
223 ///////////////////////////////////////////////////////////////////////////////
224 // want to use chat from the ppp package?
225 // note: some OS's do not need "-e" for echo to print control characters
226 // note: chat might send bytes one by one
227 // with AIX, a similar program is available under the name "pppdial"
228 $ socat -d -d tcp:localhost:25,crlf,nodelay exec:'/usr/sbin/chat -v -s "\"220 \"" "\"HELO loopback\"" "\"250 \"" "\"MAIL FROM: <hugo@localhost>\"" "\"250 \"" "\"RCPT TO: root\"" "\"250 \"" "\"DATA\"" "\"354 \"" "\"test1'$(echo -e "\r.")'\"" "\"250 \"" "\"QUIT\"" "\"221 \""',pty,echo=0,cr
229
230 //////////////////////////////////////////////////////////////////////////////
231 // IP6
232
233 # socat readline TCP6:[::1]:21 # if your inetd/ftp is listening on ip6
234
235 //////////////////////////////////////////////////////////////////////////////
236 // VSOCK
237 # start a linux VM with cid=21
238 # qemu-system-x86_64 -m 1G -smp 2 -cpu host -M accel=kvm \
239 # -drive if=virtio,file=/path/to/fedora.img,format=qcow2 \
240 # -device vhost-vsock-pci,guest-cid=21
241
242 # guest listens on port 1234 and host connects to it
243 guest$ socat - vsock-listen:1234
244 host$ socat - vsock-connect:21:1234
245
246 # host (well know CID_HOST = 2) listens on port 4321 and guest connects to it
247 host$ socat - vsock-listen:4321
248 guest$ socat - vsock-connect:2:4321
249
250 ///////////////////////////////////////////////////////////////////////////////
251 // application server solutions
252 // run a program (here: /bin/sh) chrooted, unprivileged;
253 // parent process stays in real / running as root
254 # socat -d -d - EXEC:/bin/sh,chroot=/home/sandbox,su=sandbox,pty
255
256 // make a program available on the network chrooted, unprivileged;
257 // parent process stays in / running as root
258 // script path is already chrooted
259 # ./socat -lm -d -d TCP-LISTEN:5555,fork EXEC:/bin/myscript,chroot=/home/sandbox,su=sandbox,pty,stderr
260 // to avoid terminal problems, you might - instead of telnet - connect using
261 $ socat -,icanon=0,echo=0 tcp:target:5555; reset
262
263
264 // access local display from ssh server, when ssh port forwarding is disabled
265 // socat must be installed on ssh server host
266 // might have to use xauth...
267 // this example is one-shot because ssh can handle only one channel
268 xterm1$ socat -d -d exec:"ssh www.dest-unreach.org rm -f /tmp/.X11-unix/X9; ~/bin/socat -d -d unix-l\:/tmp/.X11-unix/X9\,fork -" unix:/tmp/.X11-unix/X0
269 xterm2$ ssh target
270 target$ DISPLAY=:9 myxapplication
271
272 // touch with perms:
273 // no race condition for perms (applied with creat() call)
274 $ socat -u /dev/null creat:/tmp/tempfile,perm=0600
275
276 // touch with owner and perms:
277 // race condition before changing owner, but who cares - only root may access
278 # socat -u /dev/null creat:/tmp/tempfile,user=user1,perm=0600
279
280 // invoke an interactive ssh with exec
281 // first example passes control chars (^C etc.) to remote server as usual
282 socat -,echo=0,raw exec:'ssh server',pty,setsid,ctty
283 // second example interprets control chars on local command line
284 socat -,echo=0,icanon=0 exec:'ssh server',pty,setsid,ctty
285 // afterwards, type "reset"!
286
287 // convince ssh to provide an "interactive" shell to your script
288 // three main versions for entering password:
289 // 1) from your TTY; have 10 seconds to enter password:
290 (sleep 10; echo "ls"; sleep 1) |socat - exec:'ssh server',pty
291 // 2) from XWindows (DISPLAY !); again 10 seconds
292 (sleep 10; echo "ls"; sleep 1) |socat - exec:'ssh server',pty,setsid
293 // 3) from script
294 (sleep 5; echo PASSWORD; echo ls; sleep 1) |./socat - exec:'ssh server',pty,setsid,ctty
295
296
297 // download with proxy CONNECT
298 // use echo -e if required for \n
299 $ (echo -e "CONNECT 128.129.130.131:80 HTTP/1.0\n"; sleep 5; echo -e "GET
300 /download/file HTTP/1.0\n"; sleep 10) |socat -d -d -t 3600 - tcp:proxy:8080,crlf
301
302 // retrieve a file from an sshd site with sourceforge style entry menu;
303 // fill in your personal values; cat lets you enter your password (will be
304 // visible on screen)
305 $ (sleep 10; read pass; echo $pass; sleep 10; echo M; sleep 5; echo cat FILENAME; sleep 10) |./socat -d -d -ly - EXEC:'ssh -c 3des -l USER cf.sourceforge.net',pty,setsid,ctty |tee FILENAME
306
307 // multicast community on local network: start the following command on all
308 // participating hosts; like a conference call:
309 # socat -d -d -d -d - udp-datagram:224.0.0.2:6666,bind=:6666,ip-add-membership=224.0.0.2:eth0,bindtodevice=eth0
310 // or
311 $ socat -d -d -d -d - udp-datagram:224.0.0.2:6666,bind=:6666,ip-add-membership=224.0.0.2:eth0
312 // possible reasons for failure:
313 // iptables or other filters (open your filters as required)
314 // packets leave via wrong interface (set route: ...)
315 // socket bound to specific address
316
317 //=============================================================================
318 // GENERIC FUNCTION CALLS
319
320 // ioctl(): open CD drive (given value valid on Linux)
321 // on my Linux system I find in /usr/include/linux/cdrom.h the define:
322 // #define CDROMEJECT 0x5309 /* Ejects the cdrom media */
323 // the following command makes something like ioctl(fd, CDROMEJECT, NULL)
324 // (don't care about the read error):
325 $ socat /dev/cdrom,o-nonblock,ioctl-void=0x5309 -
326
327 // setsockopt(): SO_REUSEADDR
328 // the following command performs - beyond lots of overhead - something like:
329 // myint=1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &myint, sizeof(myint))
330 $ socat -u udp-recv:7777,setsockopt-int=1:2:1 -
331 // setsockopt(): SO_BINDTODEVICE
332
333 // ways to apply SO_BINDTODEVICE without using the special socat address option
334 // so-bindtodevice:
335 // with string argument:
336 $ sudo ./socat tcp-l:7777,setsockopt-string=1:25:eth0 pipe
337 // with binary argument:
338 $ sudo ./socat tcp-l:7777,setsockopt-bin=1:25:x6574683000 pipe
339
340 ===============================================================================
341
342 // not tested, just ideas, or have problems
343
344
345 // traverse firewall for making internal telnet server accessible for outside
346 // telnet client, when only outbound traffic (syn-filter) is allowed:
347 // on external client run "double server". this process waits for a
348 // connection from localhost on port 10023, and, when it is established, waits
349 // for a connection from anywhere to port 20023:
350 ext$ socat -d TCP-LISTEN:10023,range=localhost TCP-LISTEN:20023
351 // on internal server run double client:
352 int$ socat -d TCP:localhost:23 TCP:extclient:10023
353 // or, with socks firewall:
354 int$ socat -d TCP:localhost:23 SOCKS:socksserver:extclient:10023
355 // login with:
356 ext$ telnet localhost 20023
357
358 // you can make a double server capable of handling multiple instances:
359 ext$ socat -d TCP-LISTEN:10023,range=localhost,fork TCP-LISTEN:20023,reuseaddr
360
361 // access remote display via ssh, when ssh port forwarding is disabled
362 $ socat -d -d EXEC:"ssh target socat - UNIX:/tmp/.X11-unix/X0" TCP-LISTEN:6030
363 $ xclock -display localhost:30
364
365 // relay multiple webserver addresses through your firewall into your DMZ:
366 // make IP aliases on your firewall, and then:
367 # socat -d -d TCP-L:80,bind=fw-addr1,fork TCP:dmz-www1:80
368 # socat -d -d TCP-L:80,bind=fw-addr2,fork TCP:dmz-www2:80
369 // and for improved security:
370 # socat -d -d TCP-L:80,bind=fw-addr3,su=nobody,fork TCP:dmz-www3:80
371
372 // proxy an arbitrary IP protocol over your firewall (answers won't work)
373 # socat -d -d IP:0.0.0.0:150,bind=fwnonsec IP:sec-host:150,bind=fwsec
374
375 // proxy an unsupported IP protocol over your firewall, point to point
376 // end points see firewall interfaces as IP peers!
377 # socat -d -d IP:nonsec-host:150,bind=fwnonsec IP:sec-host:150,bind=fwsec
378 // note that, for IPsec, you might face problems that are known with NAT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment