Welcome to Session 2 of our Cyber Security Challenge Training and we re gonna capture some shells 🙂
Last Updated: 2024-01-02
Linux Shell Basics, Tips and Tricks, to help you with CTFs and also #ACSC Challenges
We will cover the following topics:
https://linux-kernel-labs.github.io/refs/heads/master/lectures/intro.html
An Operating system runs applications and the kernel translates to the hardware. A shell or terminal is a method of interacting with the entire operating system as a human without a graphical user interface (GUI). That means, that the shell is located in user space
and the (human) agent uses the shell
to interact with kernel space
via so-called utilities
or commands
, (used here synonymously).
Instructions entered in response to the shell prompt have the following syntax:
command [arg1] [arg2] .. [argn]
The shell
parses the words or tokens (commandname , options, filesnames[s]) and gets the kernel
to execute the commands assuming the syntax is good.
Unix is a multi user environment
$ whoami croedig $ id uid=1000(coder) gid=1000(coder) groups=1000(coder),999(docker) $ groups coder docker $ cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin
Let's talk about the last command:
How many other users are logged in (or how many terminals do I and them have open)?
$ who croedig $ su - croedig $ $ sudo cat /etc/shadow root:*:19702:0:99999:7::: daemon:*:19702:0:99999:7::: bin:*:19702:0:99999:7::: $ sudo su - #
On Linux, there is always a root user, almost exclusively with id=0 (the highest named user is 60000.
Root is all-powerful and it is impossible to restrict its access.
Another important concept is sudo (superuser do), where a command is executed by the normal user on behalf of the superuser.
Each process has 3 user ids:
"Real" id: the owning user
"Effective" id : determines privileges
"Saved" id: set by exec to match the effective id
Conversely, each file is owned by 1 user id !
However, the god-like privileges of root are sub-structured into so-called capabilities, you can find your current capabilities using capsh. https://man7.org/linux/man-pages/man7/capabilities.7.html or https://0xn3va.gitbook.io/cheat-sheets/container/overview/basics
$ cat /proc/$$/status | grep Cap CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: 00000000a80425fb CapAmb: 0000000000000000 $ capsh --decode=00000000a80425fb 0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap $ getcap -r / 2>/dev/null will search for binaries with capabilities
Under POSIX, any file (and everything is a file, after all) has three permissions set by default, user, group and others.
Owner Group Other
r w x r w x r w x
4 2 1 4 2 1 4 2 1
When a file is created its permissions are restricted by the umask of the process that created it.
These are the examples from the symbolic notation section given in octal notation:
Symbolic notation | Numeric notation | English |
| 0000 | no permissions |
| 0700 | read, write, & execute only for owner |
| 0770 | read, write, & execute for owner and group |
| 0777 | read, write, & execute for owner, group and others |
| 0111 | execute |
| 0222 | write |
| 0333 | write & execute |
| 0444 | read |
| 0555 | read & execute |
| 0666 | read & write |
| 0740 | owner can read, write, & execute; group can only read; others have no permissions |
https://en.wikipedia.org/wiki/File-system_permissions
An important command here is the chmod, to modify the permissions:
$ chmod +x exe.sh // makes it executable $ stat .bashrc File: .bashrc Size: 3106 Blocks: 8 IO Block: 4096 regular file Device: 10002eh/1048622d Inode: 399403 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2021-10-15 10:06:05.000000000 +0000 Modify: 2021-10-15 10:06:05.000000000 +0000 Change: 2024-01-15 12:32:45.847306257 +0000 Birth: 2024-01-15 12:32:45.847306257 +0000 $ chmod 600 mykey Sets a sensitive file to be rw only by the user $ sudo usermod -aG docker coder
You also might find chown similarly useful.
Important for Security are very much the not so commonly known SETUID SETGUID and sticky bits, that let a program be executed under either user or group that is not itself.
Note the "s" in the permissions displayed below. This represents the SETUID bit and allows
Lets look at a famous example : ping, it requires to open a socket, which corresponds to the CAP_NET_RAW capability. Most systems wont allow an end-user to set capabilities, so instead the SETUID bit is set:
$ sudo apt update && sudo apt install inetutils-ping ... $ which ping ping: /usr/bin/ping $ setcap cap_net_raw+p /usr/bin/ping unable to set CAP_SETFCAP effective capability: Operation not permitted $ stat /usr/bin/ping File: /usr/bin/ping Size: 78480 Blocks: 160 IO Block: 4096 regular file Device: 10002eh/1048622d Inode: 531677 Links: 1 Access: (4755/-rwsr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2024-01-15 12:51:53.000000000 +0000 Modify: 2023-08-15 13:13:06.000000000 +0000 Change: 2024-01-15 12:51:53.867136654 +0000 Birth: 2024-01-15 12:51:53.855136677 +0000 File: /usr/bin/ping $ cat /proc/$$/status | grep Cap
You need to tell your shell where your executables are to be searched for.
Lets say you want to find out which binary is executed when you type bash:
$ which bash /bin/bash $ whereis bash bash: /bin/bash /usr/share/man/man1/bash.1
Maybe you have your own binaries lying around in custom locations (in the following example I want to use locally built nodejs modules), so you need to update the PATH where they will be search for:
$ echo PATH /Users/croedig/Downloads/google-cloud-sdk/bin:/Users/croedig/.rd/bin:/usr/local/opt/gnupg@2.2/bin:/usr/local/bin:/usr/local/MacGPG2/bin:/Library/TeX/texbin:/Applications/VMware Fusion.app/Contents/Public:/Users/croedig/.orbstack/bin:/Users/croedig/go/bin $ export PATH="./node_modules/.bin/:$PATH"
Last, we should talk quickly about ENVIRONMENT: each process has attached to it an ASCII table of key=value pairs that describe its settings. These are also stored in address space and when we create a process from a parent process, the env will be the same (in the beginning). These values can include very juicy details that give you clues about the process and maybe even passwords or connection strings.
$ env TERM_PROGRAM=Apple_Terminal SHELL=/bin/zsh P9K_SSH=0 ZSH=/Users/croedig/.oh-my-zsh GOPATH=/Users/croedig/go GOROOT=/usr/local/go LC_CTYPE=UTF-8 REDIS_SERVER=127.0.0.1:6543
As users, we may be interested in what is going on between an application and the OS, or simply what is generally happening all over the OS. To this end, there are a plethora of utilities for us to find, inspect, trace and interact with the Linux OS.
Shells are ways to interact with processes. At system boot, there is just a single process (init). It subsequently gets forked until there are many processes, some running in kernel mode and some in user land.
There is a convention that a process expects to inherit (at each fork) from its parents two open file descriptors, 0 and 1.
In modern OS, we use terminal emulators and you can find them under
/dev/pts (pseudo terminal slaves0
/dev/tty (controlling terminal file)
/dev/ttyN (virtual console terminal file)
https://www.youtube.com/watch?v=07Q9oqNLXB4
Should you encounter a "shell-script" (something, with a .sh extension or something that you identify as a shell syntax) but that somehow doesn't work in bash but has no shebang (!#/bin/sh
or #!/usr/bin/env bash
) you should check if it is was written for a different dialect of shell.
List your available shells and then change to zsh
$ cat /etc/shells # List of acceptable shells for chpass(1). # Ftpd will not allow users to connect who are not using # one of these shells. /bin/bash /bin/csh /bin/dash /bin/ksh /bin/sh /bin/tcsh /bin/zsh $ chsh -s /bin/zsh
When you want the output from the commands run in a shell without affecting your current shell, you can spawn a sub-shell:
Using sub-shells (uses brackets)
$ export pid=$(pidof myprocess) $ (cd /; ls -la;)
This is also used often for spawning processes to be run in the background (using the " &
" operator at the end of the command)
bash
in favour of zsh
command
shell is that old-fashioned black thing ... that only Windows people know what to do with... It only runs on WindowsOver time, we hope to update this with a selection of materials for you to use online/free.
Please navigate to the Linux tile and select your favourite content. In general, you can do these labs in your own time, we will do one together today.
https://killercoda.com/pawelpiwosz/course/linuxFundamentals
Please select Lesson 2 : Your best friend - man
Man pages in linux are "manuals" and they are live savers, especially for commands that have obscure and endless options and parameters.
Here is a list of labs that can be consumed for free (sometimes after a signup)
An online set of challenges hosted on a VM that you ssh to from your machine. You will be executing the commands remote, so apart from ssh you don't need anything installed on your machine.
Somebody noticed that it's easy to waste time if you misread characters (cough cough), maybe increase your zoom level to avoid this problem.
Navigate to https://overthewire.org/wargames/bandit and start at Level0.
For your increased productivity
xargs
is a command line utility that executes whatever you feed it from STOUT
find
can literally find anything, it is extremely powerful
find . -type d -empty | xargs rmdir find . -type f -name "*.txt" | xargs -I{} mv {} {}.bak
The first command removes all empty directories, the second renames all .txt files to .bak files ( the curly brackets are placeholders).
One note on piped commands: they will break at an error (not continue after they throw an error), so that can be annoying. In that case you could also combine find with exec.
Read this detailed explanation here https://www.everythingcli.org/find-exec-vs-find-xargs/
// bring back the historical command (4 commands ago in this example) $ !-4 // ctrl +R opens the history search $ bck-i-search: _ // go back to previous directory (works like a toggle) $ cd - // repeat previous command $ !! // recursive wildcard (depends on shell, see screenshot) $ ls -l examples/**/secret*/**/ // retrieve the PID of my current process $ echo $$
A couple notable utilities
$ tree $ touch $ lsblk lsns $ pidof
Networking: what is going on on ports
$ sudo lsof -i -P -n | grep LISTEN $ sudo netstat -tulpn | grep LISTEN $ sudo ss -tulpn | grep LISTEN $ sudo lsof -i:22 ## see a specific port such as 22 ## $ sudo nmap -sTU -O IP-address-Here
And a personal favourite (written by Jess Frazelle) https://github.com/genuinetools/amicontained that tells me A LOT about where I am running on (even if I m not in a container).
$ wget amicontained https://github.com/genuinetools/amicontained/releases/download/v0.4.9/amicontained-linux-amd64; chmod +x amicontained-linux-amd64; ./amicontained-linux-amd64 Container Runtime: docker Has Namespaces: pid: true user: false AppArmor Profile: cri-containerd.apparmor.d (enforce) Capabilities: BOUNDING -> chown dac_override fowner fsetid kill setgid setuid setpcap net_bind_service net_raw sys_chroot mknod audit_write setfcap Seccomp: disabled Blocked Syscalls (28): MSGRCV SYSLOG SETUID SETGID SETSID SETREUID SETREGID SETGROUPS SETRESUID SETRESGID VHANGUP PIVOT_ROOT ACCT SETTIMEOFDAY SWAPON SWAPOFF REBOOT SETHOSTNAME SETDOMAINNAME INIT_MODULE DELETE_MODULE FUTIMESAT UTIMENSAT FANOTIFY_INIT OPEN_BY_HANDLE_AT FINIT_MODULE KEXEC_FILE_LOAD BPF Looking for Docker.sock
Search on github for CTF relevant gists, like these
https://gist.github.com/FrankSpierings/4af182c7c3aee32796792d35bedbe0fb
What else should / could I find out from my shell?
What is this shell running on? Where ? How contained? Virtualized? On-prem or in the cloud?
In real life, it can be pretty important to understand the periphery or the surrounding of my shell.
Let's do some recon
sudo apt-get install dmidecode
dmidecode -s system-manufacturer
sudo dmesg | grep "Hypervisor detected"
Aha , so this particular shell runs on a VM
A quick google on "openstack" tells us that this is likely a private cloud ( advanced users would use this recon intelligence to search for a standard architecture of Openstack and for known exploits or weaknesses)
But on another shell you might get this instead
So we're inside an Ubuntu container, which I would follow-up with a dump of
$ env
$ uname -a
$ cat /etc/os-release
$ lsb_release -a
Which tells me that I'm on a container orchestration system called kubernetes, ( which again has a reference architecture and known weaknesses): Also, the fact that I'm in a container, tells us that it will likely by minimized i.e. ship very few utilities. For containers , the amicontained
utility gives us lots of info.
Additionally, I can infer the layout of a monitoring design of the system from knowing if I'm dealing with a cloud or a traditional deployment.
Depending on what you are doing, you might want to be „quiet" on a system, so as to not alert a Soc team of your presence (there are types of purple team exercises that test if an adversary could be hiding within the system without detection) . Generally speaking network enumeration or wide scanning is very noisy and suspicious.
This is a vast and advanced topic, but it bears mentioning that it is generally very useful to check what type of host I'm executing something on.
Draw a small diagram of how your network connection looks like: protocol, ports, hostname, operating system, how many users are there, what rights do I have. Is this connection encrypted ?
Sniff your own traffic ( wireshark or similar) and find the connection: what do you see there?
( this exercise will very likely be explained in the ‚network basics‘ ) lab
Fear not, we got you covered
Once you ve been given credentials, please navigate to Sign in to Coder
Login and then press this button (or select "Create New Workspace with the "Robot" logo)
Once your workplace is provisioned, please press the Terminal button on the right, and a webterminal will appear from which you can connect to the bandit game.
Congratulations, you've successfully completed this training