Bootcamp: Linux Olympics

The Linux Olympics is an interactive, self-paced event with integrated hints to help us build our skills at completing common tasks in the Linux terminal. In this exercise, we will have the chance to build our skills and complete command-line tasks including using common Linux commands, navigating the Linux file system, working with file and directory permissions, managing Linux processes, working with Linux networking, and leveraging powerful commands for text file processing.

Let's start the Bootcamp Exercise.

sec504@slingshot:~$ bootcamp

Training: Common Commands

1) The ls command is used to list files. List the files in your home directory.

olympian@bc-commoncommands:~$ ls

2) The 'cat' command is used to display the contents of a file. Display the contents of the fencing.txt file.

olympian@bc-commoncommands:~$ cat fencing.txt

3) In Linux, files that begin with a . are hidden by default. List the hidden and non-hidden files in your home directory using 'ls -a'.

olympian@bc-commoncommands:~$ ls -a

4) Display the content of .fencingfact1.txt file.

olympian@bc-commoncommands:~$ cat .fencingfact1.txt

5) The 'pwd' command prints the name of the working directory. Identify the current directory name.

olympian@bc-commoncommands:~$ pwd

6) The 'cd' command is used to change to a new directory. Change to the epee directory.

olympian@bc-commoncommands:~$ cd epee

7) Display the fencing fact in the epee directory.

olympian@bc-commoncommands:~/epee$ ls -a
olympian@bc-commoncommands:~/epee$ cat .fencingfact2.txt

8) The 'mkdir' command is used to create a new directory. Create a directory called bout, then change to the new directory.

olympian@bc-commoncommands:~/epee$ mkdir bout
olympian@bc-commoncommands:~/epee$ cd bout

9) Running 'cd' with no arguments returns to the home directory. Return to the home directory.

olympian@bc-commoncommands:~/epee/bout$ cd

10) The 'whoami' command will display your user name. What is your user name?

olympian@bc-commoncommands:~$ whoami

11) The 'id' command displays your user name, user ID, and group information. What is your user ID?

olympian@bc-commoncommands:~$ id

12) Display the fencing fact in the foil directory.

olympian@bc-commoncommands:~$ ls
olympian@bc-commoncommands:~$ cd foil
olympian@bc-commoncommands:~/foil$ ls -a
olympian@bc-commoncommands:~/foil$ cat fencingfact3.txt

13) Display the final fencing fact in the sabre directory.

olympian@bc-commoncommands:~$ cd ..
olympian@bc-commoncommands:~$ ls
olympian@bc-commoncommands:~$ cd sabre
olympian@bc-commoncommands:~/sabre$ ls -a
olympian@bc-commoncommands:~/sabre$ cat fencingfact4.txt

14) The 'rm' command is used to remove files. Remove the fencingfact4.txt file.

olympian@bc-commoncommands:~/sabre$ rm fencingfact4.txt

15) The 'mv' command is used to move a file to a new directory. Change to the foil directory. Move the fencingfact3.txt file to /tmp.

olympian@bc-commoncommands:~/sabre$ cd ..
olympian@bc-commoncommands:~$ cd foil
olympian@bc-commoncommands:~/foil$ mv fencingfact3.txt /tmp

16) The 'mv' command is also used to rename files. Change to the /tmp directory, then rename the fencingfact3.txt file to fact.txt

olympian@bc-commoncommands:~/foil$ cd /tmp
olympian@bc-commoncommands:~/tmp$ mv fencingfact3.txt fact.txt

Training: File System

1) The Linux file system uses absolute and relative path references. Absolute paths always start with a '/'. Change to the /var/tmp/badminton directory using an absolute.

olympian@bc-filesystem:~$ cd /var/tmp/badminton

2) Display the badminton fact in the /var/tmp/badminton directory.

olympian@bc-filesystem:/var/tmp/badminton$ ls 
olympian@bc-filesystem:/var/tmp/badminton$ cat badmintonfact1.txt 

3) Relative paths can also be used in Linux without a leading '/'. Change to the ../badminton2 directory using a relative path.

olympian@bc-filesystem:/var/tmp/badminton$ cd ../badminton2

4) Display the badminton fact in the /var/tmp/badminton2 directory.

olympian@bc-filesystem:/var/tmp/badminton$ cat badmintonfact2.txt

5) Relative paths can use multiple '..' indicators to travel up several directories. Change to the ../../../tmp directory using a relative path.

olympian@bc-filesystem:/var/tmp/badminton$ cd ../../../tmp

6) Display the badminton fact in the /tmp directory.

olympian@bc-filesystem:/tmp$ cat badmintonfact3.txt 

7) The find command uses the basic syntax 'find [starting directory] -name "wildcard"'. Use the find command to list all files matching *.txt in /home.

olympian@bc-filesystem:/tmp$ find /home -name "*.txt"

8) Repeat the 'find' command, this time displaying all files ending in .TXT in /home.

olympian@bc-filesystem:/tmp$ find /home -iname "*.TXT"

8) Repeat the 'find' command, this time displaying all files ending in any case combination of .TXT in /home or in /tmp.

olympian@bc-filesystem:/tmp$ find /home /tmp -iname "*.TXT" 

9) Display the new badminton fact in the /tmp directory.

olympian@bc-filesystem:/tmp$ cat .badmintonfact7.txt

10) The find command can display output similar to the ls command using the -ls argument. Display the file list information for all badminton facts in /home.

olympian@bc-filesystem:/tmp$ find /home -iname "*.TXT" -ls

11) The find command can also search for files based on size. Identify the badminton fact file in /home that is 72 bytes in size (-size 72c).

olympian@bc-filesystem:/tmp$ find /home -size 72c

12) Display all of the badminton facts in /var, /tmp, and /home using find's -exec feature and cat.

olympian@bc-filesystem:/tmp$ find /home /tmp /var -iname "*badmin*" -exec cat {} \;;

Training: Permissions

1) Linux uses discretionary permissions on all files for the owner, the group, and other. Identify the owner of the racewalkingfact1.txt file.

olympian@bc-permissions:~$ ls -l racewalkingfact1.txt

2) Attempt to examine the contents of the racewalkingfact1.txt file.

olympian@bc-permissions:~$ cat racewalkingfact1.txt

3) You cannot examine the racewalkingfact1.txt file since you don't have permissions to read the file. Change the file permissions by running 'chmod 600 racewalkingfact1.txt'.

olympian@bc-permissions:~$ chmod 600 racewalkingfact1.txt

4) The permission 600 indicates read/write for owner (6), no permission for group (0) and no permission for other (0).

Re-examine the permissions of the racewalkingfact1.txt file.

olympian@bc-permissions:~$ ls -l racewalkingfact1.txt

5) Notice how the permission information for the file has changed from ---------- to -rw-------. Display the contents of the racewalkingfact1.txt file.

olympian@bc-permissions:~$ cat racewalkingfact1.txt

6) Linux supports octal notation for permissions where 4=read, 2=write, 1=execute. Adding the values together produces the desired permission. Change the permission for racewalkingfact2.txt so it is owner and group readable.

olympian@bc-permissions:~$ chmod 440 racewalkingfact2.txt

7) Display the contents of the racewalkingfact2.txt file.

olympian@bc-permissions:~$ cat racewalkingfact2.txt

8) Using octal notation (4=read, 2=write, 1=execute), change the permission of racewalkingfact3.txt so it is read/write by owner, read by group, and no permissions for other.

olympian@bc-permissions:~$ chmod 640 racewalkingfact3.txt

9) Display the contents of the racewalkingfact3.txt file.

olympian@bc-permissions:~$ cat racewalkingfact3.txt 

10) Using octal notation (4=read, 2=write, 1=execute), change the permission of racewalkingfact4.txt so it is read/write by owner, read/write by group, and read for other.

olympian@bc-permissions:~$ chmod 664 racewalkingfact4.txt

11) Display the contents of the racewalkingfact4.txt file.

olympian@bc-permissions:~$ cat racewalkingfact4.txt 

12) The racewalkingfact5.py file is a Python script. Display the contents of the racewalkingfact5.py file.

olympian@bc-permissions:~$ cat racewalkingfact5.py
olympian@bc-permissions:~$ ls -l racewalkingfact5.py
olympian@bc-permissions:~$ chmod 600 racewalkingfact5.py
olympian@bc-permissions:~$ cat racewalkingfact5.py

13) Using octal notation (4=read, 2=write, 1=execute), change the permission of racewalkingfact5.py so it is read/write/execute by owner, read/execute by group, and read/execute for other.

olympian@bc-permissions:~$ chmod 755 racewalkingfact5.py

14) When a file has the execute bit set, it can be run as a program. Execute the racewalkingfact5.py script: ./racewalkingfact5.py

olympian@bc-permissions:~$ ./racewalkingfact5.py

15) The execute permission is also used for directories. Attempt to change to the racewalkingfact6 directory.

olympian@bc-permissions:~$ ls -ld racewalkingfact6

16) Change the permission of racewalkingfact6 to 755.

olympian@bc-permissions:~$ chmod 755 racewalkingfact6

17) Change to the racewalkingfact6 directory, display the race walking fact, then change back to your home directory using a relative path.

olympian@bc-permissions:~$ cd racewalkingfact6
olympian@bc-permissions:~/racewalkingfact6$ cat racewalkingfact6.txt 
olympian@bc-permissions:~/racewalkingfact6$ cd ../

18) Display the permissions for the racewalkingfact7.txt file.

olympian@bc-permissions:~$ ls -la racewalkingfact7.txt

19) File ownership is controlled by the chown command. Attempt to change the ownership of the racewalkingfact7.txt file to the olympian user with the chown command.

olympian@bc-permissions:~$ chown olympian racewalkingfact7.txt

20) Only the root user can change the ownership of a file. Repeat the last chown command, this time adding the sudo command to the beginning of the command.

olympian@bc-permissions:~$ sudo chown olympian racewalkingfact7.txt

21) Display the contents of the racewalkingfact7.txt file.

olympian@bc-permissions:~$ cat racewalkingfact7.txt

22) Unlike ownership, a user can change a group assignment to any other group where they are a member. Change the group of racewalkingfact8.txt to athlete using the chgrp command.

olympian@bc-permissions:~$ chgrp athlete racewalkingfact8.txt 

23) Display the contents of the racewalkingfact8.txt file.

olympian@bc-permissions:~$ cat racewalkingfact8.txt
olympian@bc-permissions:~$ ls -la racewalkingfact8.txt
olympian@bc-permissions:~$ chmod 600 racewalkingfact8.txt 
olympian@bc-permissions:~$ cat racewalkingfact8.txt

24) The racewalkingfact9 file is a compiled program. Change the file so that it is read/write/executable for the owner, read/executable for group and other.

olympian@bc-permissions:~$ chmod 755 racewalkingfact9

25) Execute the racewalkingfact9 program.

olympian@bc-permissions:~$ ./racewalkingfact9 

26) The permission 755 implies a leading zero: 0755. When you set the leading 0 to 4, the file is SETUID, and will run with the permissions of the owner, not the user running the program. Change the owner of racewalkingfact9 to root.

olympian@bc-permissions:~$ sudo chown root racewalkingfact9 

27) SETUID files can be dangerous on the file system, since they grant privileges of the file owner. Change the permission of racewalkingfact9 to 4755 to make it SETUID.

olympian@bc-permissions:~$ chmod 4755 racewalkingfact9

28) Execute the racewalkingfact9 program as a normal user.

olympian@bc-permissions:~$ ./racewalkingfact9

29) An attacker with root access can use SETUID permissions to create a backdoor. Copy the /bin/bash file to /tmp/backdoor.

olympian@bc-permissions:~$ cp /bin/bash /tmp/backdoor

30) An attacker with root access can use SETUID permissions to create a backdoor. Change the ownership of /tmp/backdoor to root.

olympian@bc-permissions:~$ sudo chown root /tmp/backdoor 

31) An attacker with root access can use SETUID permissions to create a backdoor. Change the SETUID of /tmp/backdoor to 4755.

olympian@bc-permissions:~$ sudo chmod 4755 /tmp/backdoor 

32) An attacker with root access can use SETUID permissions to create a backdoor. We have revoked your sudo access, but you can still get root access by running the backdoor command with the -p argument.

olympian@bc-permissions:~$ /tmp/backdoor -p

Training: Processes

1) The 'ps' command is used to list running process information. List the processes for your user account.

olympian@bc-processes:~$ ps

2) Running 'ps' only lists processes for your current session. Adding the '-f' flag to the 'ps' command displays additional process detail including command line arguments. List the command line arguments and other details associated with your processes.

olympian@bc-processes:~$ ps -f

3) Adding the '-w' flag to the 'ps -f' command displays wide output. Obtain the wide output for the trampolinefact1 process.

olympian@bc-processes:~$ ps -fw

4) Adding two '-w' flags to the 'ps -f' command displays wide output without truncation. Obtain the full command line argument output for the trampolinefact1 process.

olympian@bc-processes:~$ ps -fww

5) Adding the '-e' flag to the 'ps -fww' command displays all processes, not just those for your current session. Identify the full command line for the trampolinefact2 process.

olympian@bc-processes:~$ ps -efww

6) Examine the file associated with the trampolinefact3 command line argument.

olympian@bc-processes:~$ ps -efww | grep trampolinefact3
#OR
olympian@bc-processes:~$ ps -eefww | grep trampolinefact3
olympian@bc-processes:~$ cat /var/log/fact3.log

7) Terminating a Process. Start the trampolinefact4 program.

olympian@bc-processes:~$ trampolinefact4

8) Terminating a Process. Since the trampolinefact4 program does not exit by itself, your prompt does not return. Send an interrupt signal (SIGINT) message to the process by pressing CTRL+C to terminate the process.

9) Terminating a Process. Programs can choose to ignore the SIGINIT message. Start the trampolinefact5 program.

olympian@bc-processes:~$ trampolinefact5

10) Terminating a Process. Attempt to terminate the process by pressing CTRL+C (SIGINT).

11) Terminating a Process. This process ignores the CTRL+C SIGINT message. Send the quit signal (SIGQUIT) by pressing CTRL+\.

12) A process that automatically runs in the background is a daemon process. Launch the trampolinefact6 program.

olympian@bc-processes:~$ trampolinefact6

13) Identify the process ID of the trampolinefact6 process.

olympian@bc-processes:~$ pidof trampolinefact6
#OR
olympian@bc-processes:~$ ps -e | grep trampolinefact6
olympian@bc-processes:~$ ps -e

14) When a process runs in the background, you send a signal using the 'kill' tool. Send the default signal (terminate signal/SIGTERM) to the trampolinefact6 process.

olympian@bc-processes:~$ kill -9 5757

15) Terminate the other trampolinefact processes.

olympian@bc-processes:~$ kill -9 196
olympian@bc-processes:~$ kill -9 576
olympian@bc-processes:~$ kill -9 755

16) Daemon processes can also ignore signals. Launch the trampolinefact7 program.

olympian@bc-processes:~$ trampolinefact7

17) Identify the process ID of the trampolinefact7 process.

olympian@bc-processes:~$ ps -e

18) When a process runs in the background, you send a signal using the 'kill' tool. Send the default signal (terminate signal/SIGTERM) to the trampolinefact7 process.

olympian@bc-processes:~$ pkill trampolinefact7
olympian@bc-processes:~$ kill 61456

19) Identify the process ID of the trampolinefact7 process.

olympian@bc-processes:~$ ps -e | grep trampolinefact7

20) Notice how the trampolinefact7 process refuses to terminate. Terminate the trampolinefact7 process using the kill signal/SIGKILL by adding '-9' to the kill command (before the process ID).

olympian@bc-processes:~$ kill -9 61456

21) Start the trampolinefact8 process.

olympian@bc-processes:~$ trampolinefact8

You can stop a running process by pressing CTRL+Z. Stop the trampolinefact8 process.

22) The 'jobs' command shows you the status of processes in your current terminal. Run the 'jobs' command.

olympian@bc-processes:~$ jobs

23) You can resume a stopped process in the background by running 'bg'. Resume the stopped trampolinefact8 process.

olympian@bc-processes:~$ bg

24) Run the 'jobs' command again to see the changed status of the trampolinefact8 process.

olympian@bc-processes:~$ jobs

25) You can return a background process to run in the foreground by running 'fg' Return the trampolinefact8 process to the foreground.

olympian@bc-processes:~$ fg 

26) Processes can also be run in the background by adding a trailing ampersand to the end of the command line. Start the trampolinefact9 process as a background task.

olympian@bc-processes:~$ trampolinefact9 &

27) Examine the running status of the trampolinefact9 process.

olympian@bc-processes:~$ jobs

28) Return the trampolinefact9 process to the foreground.

olympian@bc-processes:~$ fg

Training: Networking

1) The modern Linux 'ip' command has replaced several other networking tools. Run the 'ip' command with no argument to see the basic usage information.

olympian@bc-networking:~$ ip

2) The 'ip' command can be confusing, so we'll examine several use examples. Run 'ip addr show' to display interface and address information.

olympian@bc-networking:~$ ip addr show

3) Notice the interface names and addresses assigned to interfaces. The 'ip addr show' command can also be shortened to 'ip a'; run this shortened command.

olympian@bc-networking:~$ ip a

4) To examine information for a specific interface, add 'dev ' to the 'ip addr show' command. Examine the 'ip addr show' detail for the eth0 device.

olympian@bc-networking:~$ ip addr show dev eth0

5) The 'ping' tool is used for basic connectivity tests. Use 'ping' to test the connection to the 172.30.0.35 host.

olympian@bc-networking:~$ ping 172.30.0.35

6) You can specify the number of ping packets to send with '-c'. Ping the 172.30.0.35 target four times.

olympian@bc-networking:~$ ping -c 4 172.30.0.35

7) You can set a static IP address using 'ip addr add <ip/mask> dev eth0' Add the IP address 10.10.10.10/24 to the eth0 interface using sudo.

olympian@bc-networking:~$ sudo ip addr add 10.10.10.10/24 dev eth0

8) Test the 10.10.10.10 IP address set on the eth0 interface using ping.

olympian@bc-networking:~$ ping -c 2 10.10.10.10

9) You can remove a static IP address using 'ip addr del <ip/mask> dev eth0' Remove the 10.10.10.10/24 IP address from the eth0 interface using sudo.

olympian@bc-networking:~$ sudo ip addr del 10.10.10.10/24 dev eth0 

10) You can examine the status of an interface as up or down using 'ip link show dev eth0'. Examine the status of the eth0 interface.

olympian@bc-networking:~$ ip link show dev eth0

11) The 'ip link set dev eth0 down' command will place the interface in the down state. This command requires root access. Change the eth0 interface to the down state.

olympian@bc-networking:~$ sudo ip link set dev eth0 down 

12) Change the eth0 interface back to the up state.

olympian@bc-networking:~$ sudo ip link set dev eth0 up

13) The 'ip route' command will display the host routing table. Display the host routing table.

olympian@bc-networking:~$ ip route

14) The 'ip neigh' command will display the host ARP table. Display the host ARP table.

olympian@bc-networking:~$ ip neigh

15) The 'netstat -na' command will list all network connections (inbound and outbound), as well as UNIX sockets. Use the netstat command to identify the outbound connection.

olympian@bc-networking:~$ netstat -na 

16) Adding the '-t' argument to the netstat command will limit the display to TCP connection information. Re-run the netstat command, this time with the argument '-nat'.

olympian@bc-networking:~$ netstat -nat

17) To focus on UDP information, change the '-t' argument to '-u'.

olympian@bc-networking:~$ netstat -nau

18) In the prior examples, the netstat command revealed a mostly idle host. Run the 'netstat -nat' command again, identifying an outbound SSH session with a state of ESTABLISHED.

olympian@bc-networking:~$ netstat -nat | grep ':22'

19) In this output you can see an SSH connection to 172.30.0.35. Use the netstat command again to identify a new TCP port that is listening (accepting connections) on the host.

olympian@bc-networking:~$ netstat -nat | grep LISTEN

20) The prior output identifies listening ports, but does not indicate which process is listening on the ports. Add the '-p' argument to identify the PID and process name information (you must be root).

olympian@bc-networking:~$ sudo netstat -natp

21) A modern replacement for netstat is the ss command, which accepts the same arguments. Examine the outbound and listening ports using the ss command.

olympian@bc-networking:~$ ss -na

Training: File Processing

1) Linux includes several tools for working with plain-text files. A simple editor for creating files is nano. Run 'nano tabletennisfact1.txt' to edit the file.

olympian@bc-files:~$ nano tabletennisfact1.txt

2) Use your arrow keys to navigate your cursor. Make any change to the file, then press CTRL+X to exit, saving your changes.

3) You can also create files using echo and shell redirection: echo "Any Content" > file Create a file named paddle using echo with the message 'ball'.

olympian@bc-files:~$ echo 'ball' > paddle 

4) Another option is to use 'cat'. You can use cat to send any input to a file using standard redirection, including several lines of text. Create a file called 'offensivehits' using cat: cat > offensivehits' . Once you've created the file, you can add anything you want. Type the word 'hit' and press Enter.

olympian@bc-files:~$ cat > offensivehits

5) You can keep adding more lines, typing or pasting text to add to the file. Type the word smash to add to the file, then press Enter. To close the file press CTRL+D.

6) Using any technique, create a file called 'defensive' with four lines: push, chop, block, and lob.

olympian@bc-files:~$ cat > defensive

7) Now you know three options for creating files: nano, echo, and cat. Next we'll look at retrieving data from files. The 'head' command will retrieve 10 lines from the beginning of a file. Run 'head /etc/passwd' to read from the beginning of the file.

olympian@bc-files:~$ head /etc/passwd

8) You can specify a number of lines other than 10 using the -n argument. Display only the first two lines from the /etc/passwd file.

olympian@bc-files:~$ head -n 2 /etc/passwd

9) The 'tail' command will retrieve 10 lines at the end of a file. Examine the last 10 lines from the /etc/passwd file.

olympian@bc-files:~$ tail /etc/passwd

10) Like head, the tail command accepts a line count with -n. Display the last 3 lines of the /etc/passwd file.

olympian@bc-files:~$ tail -n 3 /etc/passwd

11) Tail can skip one or more lines with -n +2 (or any other number). This is useful if you want to skip the first or last line in the file. Read the /etc/passwd file, starting at the 2nd line from the beginning of the file.

olympian@bc-files:~$ tail -n +2 /etc/passwd

12) The 'grep' command is a powerful tool, allowing you to search for one or more lines in a file or any stream of data: grep searchterm filename Use grep to search for the string 'players' in all .txt files in your home directory.

olympian@bc-files:~$ grep players *.txt

13) Adding the '-C2' argument to grep adds two lines of context to the matched output; by default, this is one line before the matched term, and one line after. Add the -C2 argument to the previous command to display added context in the search results.

olympian@bc-files:~$ grep -C2 players *.txt

14) By default, grep performs a case-sensitive search. Add the -i argument to perform a case-insensitive search. Identify the two files with the word 'minute' in the table tennis fact .txt files with 2 lines of context.

olympian@bc-files:~$ grep -C2 -i 'minute' *.txt  

15) Working with text files, we often want to collect basic stats on the file. This is possible through the 'wc' (word count) tool. Use the wc tool to collect basic information for the tabletennisfact4.txt file.

olympian@bc-files:~$ wc tabletennisfact4.txt

16) In this output, wc tells us that the file has 2 lines, 23 words, and 116 characters (including new line markers). Add the -l argument to obtain just a line count from the file.

olympian@bc-files:~$ wc -l tabletennisfact4.txt

17) Linux also excels at sorting and removing duplicates lines from basic files. Start by examining the first several lines of the tabletennisfact5.txt file.

olympian@bc-files:~$ head tabletennisfact5.txt

18) This file lists several variations of table tennis paddle rubbers. Count the number of lines in the file.

olympian@bc-files:~$ wc -l tabletennisfact5.txt

19) The 'sort' tool sorts the contents of a file alphabetically and numerically: sort filename. Sort the file contents alphabetically using the 'sort' tool.

olympian@bc-files:~$ sort tabletennisfact5.txt

20) Pipelining is when we take the output of one tool and send it to another tool using a pipe: | Repeat the tail command and count the number of lines.

olympian@bc-files:~$ tail -n +5 tabletennisfact5.txt | wc -l

21) Instead of counting the number of lines, send the tail output to the sort command to sort the output.

olympian@bc-files:~$ tail -n +5 tabletennisfact5.txt | sort 

22) The sorted output shows some duplicate entries. Add the -u argument to sort to make the output unique (eliminating duplicate lines).

olympian@bc-files:~$ tail -n +5 tabletennisfact5.txt | sort -u

23) Count the number of sorted, unique paddle types by adding another pipeline with 'wc -l'.

olympian@bc-files:~$ tail -n +5 tabletennisfact5.txt | sort -u | wc -l

24) Adding the -n argument to sort will cause it to treat input as numbers and sort numerically. Sort the tabletennisfact5.txt file using the numeric sort option.

olympian@bc-files:~$ tail -n +5 tabletennisfact5.txt | sort -n

25) The 'cut' command allows you to cut selected portions of text. This is often valuable when working with delimited files. Examine the first several lines of the tabletennisfact6.csv file.

olympian@bc-files:~$ head  tabletennisfact6.csv 

26) The first line of tabletennisfact6.csv indicates the row titles for this CSV file. We can use cut to specify a comma delimiter '-d ,' to access a field by the column number ('-f 1' for the first column). Access the name column of the tabletennisfact6.csv file using cut.

olympian@bc-files:~$ cut -d ',' -f 1  tabletennisfact6.csv 

27) Use a pipeline to count the number of unique Olympic cities in the tabletennisfact6.csv file (removing the initial header line).

olympian@bc-files:~$ tail -n +2 tabletennisfact6.csv | cut -d ',' -f 11 | sort -u | wc -l

28) The field specifier can accept a comma-separated list of fields to retrieve multiple columns from the data: -f 1,2,4 Retrieve the Olympic city and the player name from the data using 'cut'.

olympian@bc-files:~$ cut -d ',' -f 1,11 tabletennisfact6.csv 

29) The 'uniq' command performs the 'sort -u' function, but has an extra feature: count the number of unique lines. Count the number of table tennis medals allocated for each Olympic year.

olympian@bc-files:~$ cut -d ',' -f 9 tabletennisfact6.csv | sort | uniq -c

30) Which two table tennis athletes have the most Olympic medals (tied)?

olympian@bc-files:~$ cut -d ',' -f 1 tabletennisfact6.csv | sort | uniq -c

Training: JSON File Processing

1) JSON is the JavaScript Object Notation, a common data format that you will use often when working with cloud assets. Display the contents of the JSON file fact1.json.

olympian@bc-json:~$ cat fact1.json 

2) JQ is a powerful tool and scripting platform to process and manipulate JSON data. In the simplest form, JQ takes JSON data and converts it into a human-readable format. Run 'jq "." fact1.json' to pretty-print the JSON file.

olympian@bc-json:~$ jq "." fact1.json 

3) JQ can also read the JSON data from standard input. This is often used with cat to read the file and pipe the contents to JQ. Display the contents of the fact1.json file with cat, then pipe the results to jq.

olympian@bc-json:~$ cat fact1.json | jq

4) JQ also validates the data content and will display an error if the content is not valid JSON. Display the contents of the file fact2.json with cat, then attempt to parse the file with JQ.

olympian@bc-json:~$ cat fact2.json | jq

5) Notice how the fact2.json file does not validate when processed by JQ, due to a missing quotation mark at the end of the line. Edit the file to add a quotation mark at the end of the string, inside the closing square bracket, then run JQ again to parse the file.

olympian@bc-json:~$ cat fact2.json | jq

6) JQ's error messages are not always as intuitive as one would like. Display the contents of the fact3.json file using cat, then attempt to decode the fact3.json file using JQ.

olympian@bc-json:~$ cat fact3.json | jq

7) JSON requires all strings to be denoted in double quotes, while JavaScript permits single quotes for strings. This can lead to inconsistencies where JQ will refuse to parse data but we can fix this with a simple script. Display the contents of the fixquotes.sh script using cat.

olympian@bc-json:~$ cat fixquotes.sh 

8) The script uses sed to convert sinqle quotes to double quotes, correcting the problematic JSON formatting. Run fixquotes.sh specifying the fact3.json file as the command line argument, sending the converted file content to JQ.

olympian@bc-json:~$ ./fixquotes.sh fact3.json | jq

9) JSON files can encode multiple data elements. Examine the file DATATYPES.json to learn more about the data types. Read all of the information contained in this file!

olympian@bc-json:~$ cat DATATYPES.json | jq

10) JSON does not support some other data types. Examine the file DATATYPES-UNSUPPORTED.json to learn more about unsupported data types. Read all of the information contained in this file!

olympian@bc-json:~$ cat DATATYPES-UNSUPPORTED.json | jq

11) JSON arrays are a common data type representing multiple data elements of all the same type. Examine the file array1.json to see an example of an array of strings.

olympian@bc-json:~$ cat array1.json | jq

12) Arrays can contain any data type, as long as all of the elements are the same type. Examine the file array2.json for an example of an array of numbers.

olympian@bc-json:~$ cat array2.json | jq

13) JSON objects are a data type that can contain any type of data using the "attribute":value syntax with multiple elements separated by commas. Examine the file object1.json to see an example of this syntax.

olympian@bc-json:~$ cat object1.json | jq

14) Here we see two attributes (year and city) with values that are different types (number and string) in a single object. Objects are often used in an array to denote multiple data elements for a given record. Examine the file object2.json to see an example of this syntax.

olympian@bc-json:~$ cat object2.json | jq

15) Here we see an array of objects, each denoting a year and a city value. Object elements can also be nested, where the data elements can contain multiple levels of arrays and objects. Examine the events.json file to see an example of this syntax. (Tip: pipe the results to more to see one screen of data at a time).

olympian@bc-json:~$ cat events.json | jq

16) JQ supports several built-in functions to perform operations on the JSON data. By specifying a function name and optional arguments, we can get additional information about the JSON data. Decode the events.json file with JQ, adding the argument 'length' to count the number of objects in the top-level JSON array.

olympian@bc-json:~$ cat events.json | jq 'length'

17) JQ allows us to extract specific information from the JSON results using dot notation. Start by accessing the first array element by adding '.[0]' (including the single quotes) to the end of the prior JQ command reading from events.json.

olympian@bc-json:~$ cat events.json | jq '.[0]'

18) If JQ cannot retrieve the information from a specified data object, it will return null. Attempt to access the 7th array element (one more than what is in the events.json array) to see this behavior.

olympian@bc-json:~$ cat events.json | jq '.[6]'

19) JQ can work with a whole collections of objects instead of a single array element. This is useful when we want to work with data collectively instead of accessing individual elements. Access the collection of objects in the array, removing the index number from the prior command (".[]"). This is known as the array selector, and is often used to process data within an array of elements.

olympian@bc-json:~$ cat events.json | jq '.[]'

20) JQ supports the concept of pipelining within the program syntax. Pipelining is similar to Linux and Windows command prompts where one command sends output to another command using the pipe character. With JQ, the pipeline is included within the quotation marks that delimit the JQ program. Repeat the last command, adding a pipe character after the array dot notation, followed by the length built-in function.

olympian@bc-json:~$ cat events.json | jq '.[] | length '

21) Here, length operates on all of the received objects, counting the number of elements for each object (the 1st through 5th objects all have three fields: year, city, and medalists; the last object only has two fields). Dot notation also allows us to access individual fields within the objects by specifing the field name. In the prior command, replace the length function with dot notation to access the year field in raw format by adding the -r argument to jq.

olympian@bc-json:~$ cat events.json | jq '.[] | .year '

22) Repeat the prior command again, this time requesting the .city object instead of the year.

olympian@bc-json:~$ cat events.json | jq -r '.[] | .city'

23) Using JQ you can access multiple elements instead of the single .city field by supplying a comma-seperated list of fields. Re-run the prior command, requesting the .year and .city elements in the JQ pipeline. Retain -r argument for raw output.

olympian@bc-json:~$ cat events.json | jq -r '.[] | .year, .city'

24) Here we see that we can request multiple fields in the JQ output using a comma-seperated list. JQ will display the fields one per line. The JQ command line argument -j changes this behavior, and will join all of the fields together. Re-run the prior command, adding the -j argument.

olympian@bc-json:~$ cat events.json | jq -j '.[] | .year, .city'

25) This output is less than useful since there is no delimeter between fields. In addition to requesting fields in the comma-seperated list, JQ also allows you to request static strings denoted in quotation marks. For example, .field1, ",", .field2 will display field1 followed by a comma, then field2. Request the year and city fields, seperated by a comma.

olympian@bc-json:~$ cat events.json | jq -j '.[] | .year, "," , .city'

26) This is closer to being useful output, but the end of the record is still immediately appended to the prior record. Add another comma-seperated string field, this time using the \n indicator to add a new line to the end of each record.

olympian@bc-json:~$ cat events.json | jq -j '.[] | .year, "," , .city, "\n"'

27) Adding static strings in JQ output is useful but awkward. JQ can simplify this process, but first we need to look at the forced type conversion feature. Within the pipeline for any single element, we can convert multiple fields to another data type such as an array by surrounding the fields with square brackets. Request the .year and .city fields in a comma-seperated list again (without the string seperators), this time putting the field list inside of square brackets.

olympian@bc-json:~$ cat events.json | jq -j '.[] | [ .year, .city ]'

28) In this output JQ has converted the year and city fields from the raw data to arrays of data, one per record. Since the data is in array format, we can use other JQ functions to manipulate the data. The JQ join function joins the elements of an array using a delimiter. Add the join(",") command to the end of the JQ pipeline; remove the raw and join command-line arguments.

olympian@bc-json:~$ cat events.json | jq '.[] | [.year, .city] | join(",")'  

29) This is useful output, and simpler to design where we don't have to add the string elements to manually seperate each field. Re-run the command, this time adding -r to produce the output in raw format, omitting the quotation marks

olympian@bc-json:~$ cat events.json | jq -r '.[] | [.year, .city] | join(",")'  

30) Converting data to CSV format is a common task for JQ. To simplify this process, JQ has a format string modifier @csv. Run the previous command again, this time removing the join(",") command and replacing it with @csv. Notice how the city string is included in quotes to preserve any string including those with spaces.

olympian@bc-json:~$ cat events.json | jq -r '.[] | [.year, .city] | @csv'  

31) We'll continue to use this command to request an additional field of information: the gold medal winner for each year. Examine the pretty JSON data from JQ to refamiliarize yourself with the data structure, accessing the array objects using .[] as the only pipeline request.

olympian@bc-json:~$ cat events.json | jq '.[]'  

32) This JSON structure includes medalist winner information nested in each of the yearly object elements. Nested objects are common in JSON, and easily accessible using dot notation. To access a nested object, specify the top-level object (.medalists) immediately followed by the nested element name (.gold or .silver or .bronze in this example). Modify the previous JQ command where we retrieved multiple fields, adding the gold medalist to the CSV output.

olympian@bc-json:~$ cat events.json | jq -r '.[] | [.year, .city, .medalists.gold] | @csv'  

33) Repeat the prior comand, adding the silver and bronze medalists.

olympian@bc-json:~$ cat events.json | jq -r '.[] | [.year, .city, .medalists.gold, .medalists.silver, .medalists.bronze ] | @csv'  

34) Next you will apply what you've learned to a new data file. Use the file topathletes.json to answer the remaining questions in this event. Use JQ to pretty print the data in the topathletes.json file.

olympian@bc-json:~$ cat topathletes.json | jq

35) Use the length function to count the number of elements in the top-level array.

olympian@bc-json:~$ cat topathletes.json | jq 'length'

36) Extract the fourth data element in the top-level array.

olympian@bc-json:~$ cat topathletes.json | jq '.[3]'

37) Extract the list of countries represented by the top modern pentathalon athletes in raw format.

olympian@bc-json:~$ cat topathletes.json | jq -r '.[] | .country'

38) Extract a list of all athlete names in the order First Last, seperated by a space, with a newline at the end of each record, in raw format.

olympian@bc-json:~$ cat topathletes.json | jq -rj '.[] | .first, " ", .last, "\n"'

39) Create a CSV data set of two colums: country followed by total medals won, in raw format. Include quotation marks around the country name.

olympian@bc-json:~$ cat topathletes.json | jq -r '.[] | [.country, .medals.total] | @csv '

Final Olympic Event

1) Identify the username of your logged-in account.

admin@bc-olympicevent:~$ whoami

2) Identify your user ID, group ID, and group assignments.

admin@bc-olympicevent:~$ id

3) List your sudo permissions.

admin@bc-olympicevent:~$ sudo -l

4) List the files in your home directory.

admin@bc-olympicevent:~$ ls -la

5) Identify the listening TCP port numbers.

admin@bc-olympicevent:~$ ss -nat

6) Continue your analysis, focusing on the system login file: /var/log/auth.log Copy the /var/log/auth.log file to your home directory.

admin@bc-olympicevent:~$ sudo cp /var/log/auth.log .

7) Change the owner and group for the /home/admin/auth.log file so that admin is the owner and admin is the group.

admin@bc-olympicevent:~$ sudo chown admin:admin auth.log 

8) Change the permissions on the /home/admin/auth.log file so that it is readable and writable by owner with no permissions for the group and no permissions for other.

admin@bc-olympicevent:~$ chmod 600 auth.log 

9) Examine the first several lines of the auth.log file.

admin@bc-olympicevent:~$ head auth.log 

10) How many times does the case-insensitive string 'failed' appear in the auth.log file?

admin@bc-olympicevent:~$ grep -i 'failed' auth.log | wc -l 

11) Examine the failed password login attempts in the auth.log file for a user other then root.

admin@bc-olympicevent:~$ grep -i "failed password" auth.log | grep -v "root"

12) Use a tool to count the number of lines in auth.log where a password is accepted.

admin@bc-olympicevent:~$ grep -i "accepted" auth.log | wc -l 

13) The auth.log doesn't necessarily indicate a successful compromise. Wardrobe99 network admins have prepared a web server access log extract for you to evaluate as well. Examine the file size of the /var/log/nginx/access.csv file.

admin@bc-olympicevent:~$ ls -lh /var/log/nginx/access.csv 
#OR
admin@bc-olympicevent:~$ du /var/log/nginx/access.csv 

14) Begin to assess the web server activity. Change to the web server log directory in /var/log/nginx.

admin@bc-olympicevent:~$ cd /var/log/nginx/

15) Examine the first few lines in the access.csv log file.

admin@bc-olympicevent:/var/log/nginx$ head access.csv 

16) How many lines are there in access.csv file?

admin@bc-olympicevent:/var/log/nginx$ wc -l access.csv 

17) How many times does phpmyadmin as a case-insensitive string appear in the logged requests?

admin@bc-olympicevent:/var/log/nginx$ grep -i "phpmyadmin" access.csv | wc -l 

18) How many times was phpmyadmin as a case-insensitive string NOT part of the logged requests?

admin@bc-olympicevent:/var/log/nginx$ cat access.csv | grep -iv "phpmyadmin" | wc -l 

19) Identify the largest HTTP response length in the access.csv file.

admin@bc-olympicevent:/var/log/nginx$ cut -d ',' -f4 access.csv | sort -n

20) Which IP address made the request to generate the longest HTTP response length?

admin@bc-olympicevent:/var/log/nginx$ cut -d ',' -f4 access.csv | sort -n | tail -1
admin@bc-olympicevent:/var/log/nginx$ longest_request=$(cut -d ',' -f4 access.csv | sort -n | tail -1)
admin@bc-olympicevent:/var/log/nginx$ grep $longest_request access.csv | cut -d ',' -f1

21) Identify any other HTTP requests that include the string shelleyz.

admin@bc-olympicevent:/var/log/nginx$ grep -i "shelleyz" access.csv 

22) The web server log indicates a possible attack involving a process called linkd. Search the process list to identify a process called linkd.

admin@bc-olympicevent:/var/log/nginx$ ps -eefww | grep linkd 
#OR
admin@bc-olympicevent:/var/log/nginx$ ps aux | grep linkd

23) Wardrobe99 management is concerned about the attacker's access for this breach and have asked you to disable network access for this server. Place the eth0 interface into the down state.

admin@bc-olympicevent:/var/log/nginx$ sudo ip link set dev eth0 down  

24) Terminate the linkd process.

admin@bc-olympicevent:/var/log/nginx$ ps -e
admin@bc-olympicevent:/var/log/nginx$ sudo kill -9 232

25) Identify the fully-qualified location of the linkd executable.

admin@bc-olympicevent:/var/log/nginx$ locate linkd

26) Finally, make the linkd process non-executable.

admin@bc-olympicevent:/var/log/nginx$ sudo chmod -x /usr/local/share/man/linkd

Last updated