简体   繁体   中英

Open a shell in the second process of a pipe

I'm having problems understanding what's going on in the following situation. I'm not familiar with UNIX pipes and UNIX at all but have read documentation and still can't understand this behaviour.

./shellcode is an executable that successfully opens a shell:

seclab$ ./shellcode
$ exit
seclab$

Now imagine that I need to pass data to ./shellcode via stdin , because this reads some string from the console and then prints "hello " plus that string. I do it in the following way (using a pipe ) and the read and write works:

seclab$ printf "world" | ./shellcode
seclab$ hello world
seclab$

However, a new shell is not opened (or at least I can't see it and iteract with it), and if I run exit I'm out of the system, so I'm not in a new shell.

Can someone give some advice on how to solve this? I need to use printf because I need to input binary data to the second process and I can do it like this: printf "\\x01\\x02..."

When you use a pipe, you are telling Unix that the output of the command before the pipe should be used as the input to the command after the pipe. This replaces the default output (screen) and default input (keyboard). Your shellcode command doesn't really know or care where its input is coming from. It just reads the input until it reaches the EOF (end of file).

Try running shellcode and pressing Control-D. That will also exit the shell, because Control-D sends an EOF (your shell might be configured to say "type exit to quit", but it's still responding to the EOF).

There are two solutions you can use:

Solution 1:

Have shellcode accept command-line arguments:

#!/bin/sh
echo "Arguments: $*"
exec sh

Running:

outer$ ./shellcode foo
Arguments: foo
$ echo "inner shell"
inner shell
$ exit
outer$

To feed the argument in from another program, instead of using a pipe, you could:

$ ./shellcode `echo "something"`

This is probably the best approach, unless you need to pass in multi-line data. In that case, you may want to pass in a filename on the command line and read it that way.

Solution 2:

Have shellcode explicitly redirect its input from the terminal after it's processed your piped input:

#!/bin/sh
while read input; do
  echo "Input: $input"
done
exec sh </dev/tty

Running:

outer$ echo "something" | ./shellcode
Input: something
$ echo "inner shell"
inner shell
$ exit
outer$

If you see an error like this after exiting the inner shell:

sh: 1: Cannot set tty process group (No such process)

Then try changing the last line to:

exec bash -i </dev/tty

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM